]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/ec/ecx_meth.c
Param builder: make the OSSL_PARAM_BLD APIs public.
[thirdparty/openssl.git] / crypto / ec / ecx_meth.c
1 /*
2 * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 /*
11 * ECDSA low level APIs are deprecated for public use, but still ok for
12 * internal use.
13 */
14 #include "internal/deprecated.h"
15
16 #include <stdio.h>
17 #include "internal/cryptlib.h"
18 #include <openssl/x509.h>
19 #include <openssl/ec.h>
20 #include <openssl/rand.h>
21 #include <openssl/core_names.h>
22 #include "openssl/param_build.h"
23 #include "crypto/asn1.h"
24 #include "crypto/evp.h"
25 #include "crypto/ecx.h"
26 #include "ec_local.h"
27 #include "curve448/curve448_local.h"
28 #include "ecx_backend.h"
29
30 typedef enum {
31 KEY_OP_PUBLIC,
32 KEY_OP_PRIVATE,
33 KEY_OP_KEYGEN
34 } ecx_key_op_t;
35
36 /* Setup EVP_PKEY using public, private or generation */
37 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
38 const unsigned char *p, int plen, ecx_key_op_t op)
39 {
40 ECX_KEY *key = NULL;
41 unsigned char *privkey, *pubkey;
42
43 if (op != KEY_OP_KEYGEN) {
44 if (palg != NULL) {
45 int ptype;
46
47 /* Algorithm parameters must be absent */
48 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
49 if (ptype != V_ASN1_UNDEF) {
50 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
51 return 0;
52 }
53 }
54
55 if (p == NULL || plen != KEYLENID(id)) {
56 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
57 return 0;
58 }
59 }
60
61 key = ecx_key_new(KEYNID2TYPE(id), 1);
62 if (key == NULL) {
63 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
64 return 0;
65 }
66 pubkey = key->pubkey;
67
68 if (op == KEY_OP_PUBLIC) {
69 memcpy(pubkey, p, plen);
70 } else {
71 privkey = ecx_key_allocate_privkey(key);
72 if (privkey == NULL) {
73 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
74 goto err;
75 }
76 if (op == KEY_OP_KEYGEN) {
77 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
78 goto err;
79 if (id == EVP_PKEY_X25519) {
80 privkey[0] &= 248;
81 privkey[X25519_KEYLEN - 1] &= 127;
82 privkey[X25519_KEYLEN - 1] |= 64;
83 } else if (id == EVP_PKEY_X448) {
84 privkey[0] &= 252;
85 privkey[X448_KEYLEN - 1] |= 128;
86 }
87 } else {
88 memcpy(privkey, p, KEYLENID(id));
89 }
90 switch (id) {
91 case EVP_PKEY_X25519:
92 X25519_public_from_private(pubkey, privkey);
93 break;
94 case EVP_PKEY_ED25519:
95 ED25519_public_from_private(pubkey, privkey);
96 break;
97 case EVP_PKEY_X448:
98 X448_public_from_private(pubkey, privkey);
99 break;
100 case EVP_PKEY_ED448:
101 /*
102 * TODO(3.0): We set the library context to NULL for now. This will
103 * need to change.
104 */
105 ED448_public_from_private(NULL, pubkey, privkey);
106 break;
107 }
108 }
109
110 EVP_PKEY_assign(pkey, id, key);
111 return 1;
112 err:
113 ecx_key_free(key);
114 return 0;
115 }
116
117 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
118 {
119 const ECX_KEY *ecxkey = pkey->pkey.ecx;
120 unsigned char *penc;
121
122 if (ecxkey == NULL) {
123 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
124 return 0;
125 }
126
127 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
128 if (penc == NULL) {
129 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
130 return 0;
131 }
132
133 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
134 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
135 OPENSSL_free(penc);
136 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
137 return 0;
138 }
139 return 1;
140 }
141
142 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
143 {
144 const unsigned char *p;
145 int pklen;
146 X509_ALGOR *palg;
147
148 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
149 return 0;
150 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
151 KEY_OP_PUBLIC);
152 }
153
154 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
155 {
156 const ECX_KEY *akey = a->pkey.ecx;
157 const ECX_KEY *bkey = b->pkey.ecx;
158
159 if (akey == NULL || bkey == NULL)
160 return -2;
161
162 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
163 }
164
165 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
166 {
167 const unsigned char *p;
168 int plen;
169 ASN1_OCTET_STRING *oct = NULL;
170 const X509_ALGOR *palg;
171 int rv;
172
173 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
174 return 0;
175
176 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
177 if (oct == NULL) {
178 p = NULL;
179 plen = 0;
180 } else {
181 p = ASN1_STRING_get0_data(oct);
182 plen = ASN1_STRING_length(oct);
183 }
184
185 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
186 ASN1_STRING_clear_free(oct);
187 return rv;
188 }
189
190 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
191 {
192 const ECX_KEY *ecxkey = pkey->pkey.ecx;
193 ASN1_OCTET_STRING oct;
194 unsigned char *penc = NULL;
195 int penclen;
196
197 if (ecxkey == NULL || ecxkey->privkey == NULL) {
198 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
199 return 0;
200 }
201
202 oct.data = ecxkey->privkey;
203 oct.length = KEYLEN(pkey);
204 oct.flags = 0;
205
206 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
207 if (penclen < 0) {
208 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
209 return 0;
210 }
211
212 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
213 V_ASN1_UNDEF, NULL, penc, penclen)) {
214 OPENSSL_clear_free(penc, penclen);
215 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
216 return 0;
217 }
218
219 return 1;
220 }
221
222 static int ecx_size(const EVP_PKEY *pkey)
223 {
224 return KEYLEN(pkey);
225 }
226
227 static int ecx_bits(const EVP_PKEY *pkey)
228 {
229 if (IS25519(pkey->ameth->pkey_id)) {
230 return X25519_BITS;
231 } else if(ISX448(pkey->ameth->pkey_id)) {
232 return X448_BITS;
233 } else {
234 return ED448_BITS;
235 }
236 }
237
238 static int ecx_security_bits(const EVP_PKEY *pkey)
239 {
240 if (IS25519(pkey->ameth->pkey_id)) {
241 return X25519_SECURITY_BITS;
242 } else {
243 return X448_SECURITY_BITS;
244 }
245 }
246
247 static void ecx_free(EVP_PKEY *pkey)
248 {
249 ecx_key_free(pkey->pkey.ecx);
250 }
251
252 /* "parameters" are always equal */
253 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
254 {
255 return 1;
256 }
257
258 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
259 ASN1_PCTX *ctx, ecx_key_op_t op)
260 {
261 const ECX_KEY *ecxkey = pkey->pkey.ecx;
262 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
263
264 if (op == KEY_OP_PRIVATE) {
265 if (ecxkey == NULL || ecxkey->privkey == NULL) {
266 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
267 return 0;
268 return 1;
269 }
270 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
271 return 0;
272 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
273 return 0;
274 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
275 indent + 4) == 0)
276 return 0;
277 } else {
278 if (ecxkey == NULL) {
279 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
280 return 0;
281 return 1;
282 }
283 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
284 return 0;
285 }
286 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
287 return 0;
288
289 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
290 indent + 4) == 0)
291 return 0;
292 return 1;
293 }
294
295 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
296 ASN1_PCTX *ctx)
297 {
298 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
299 }
300
301 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
302 ASN1_PCTX *ctx)
303 {
304 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
305 }
306
307 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
308 {
309 switch (op) {
310
311 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
312 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
313 KEY_OP_PUBLIC);
314
315 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
316 if (pkey->pkey.ecx != NULL) {
317 unsigned char **ppt = arg2;
318
319 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
320 if (*ppt != NULL)
321 return KEYLEN(pkey);
322 }
323 return 0;
324
325 default:
326 return -2;
327
328 }
329 }
330
331 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
332 {
333 switch (op) {
334 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
335 /* We currently only support Pure EdDSA which takes no digest */
336 *(int *)arg2 = NID_undef;
337 return 2;
338
339 default:
340 return -2;
341
342 }
343 }
344
345 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
346 size_t len)
347 {
348 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
349 KEY_OP_PRIVATE);
350 }
351
352 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
353 {
354 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
355 KEY_OP_PUBLIC);
356 }
357
358 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
359 size_t *len)
360 {
361 const ECX_KEY *key = pkey->pkey.ecx;
362
363 if (priv == NULL) {
364 *len = KEYLENID(pkey->ameth->pkey_id);
365 return 1;
366 }
367
368 if (key == NULL
369 || key->privkey == NULL
370 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
371 return 0;
372
373 *len = KEYLENID(pkey->ameth->pkey_id);
374 memcpy(priv, key->privkey, *len);
375
376 return 1;
377 }
378
379 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
380 size_t *len)
381 {
382 const ECX_KEY *key = pkey->pkey.ecx;
383
384 if (pub == NULL) {
385 *len = KEYLENID(pkey->ameth->pkey_id);
386 return 1;
387 }
388
389 if (key == NULL
390 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
391 return 0;
392
393 *len = KEYLENID(pkey->ameth->pkey_id);
394 memcpy(pub, key->pubkey, *len);
395
396 return 1;
397 }
398
399 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
400 {
401 /*
402 * We provide no mechanism to "update" an ECX key once it has been set,
403 * therefore we do not have to maintain a dirty count.
404 */
405 return 1;
406 }
407
408 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
409 EVP_KEYMGMT *to_keymgmt)
410 {
411 const ECX_KEY *key = from->pkey.ecx;
412 OSSL_PARAM_BLD tmpl;
413 OSSL_PARAM *params = NULL;
414 int selection = 0;
415 int rv = 0;
416
417 OSSL_PARAM_BLD_init(&tmpl);
418
419 /* A key must at least have a public part */
420 if (!OSSL_PARAM_BLD_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
421 key->pubkey, key->keylen))
422 goto err;
423 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
424
425 if (key->privkey != NULL) {
426 if (!OSSL_PARAM_BLD_push_octet_string(&tmpl,
427 OSSL_PKEY_PARAM_PRIV_KEY,
428 key->privkey, key->keylen))
429 goto err;
430 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
431 }
432
433 params = OSSL_PARAM_BLD_to_param(&tmpl);
434
435 /* We export, the provider imports */
436 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
437
438 err:
439 OSSL_PARAM_BLD_free(params);
440 return rv;
441 }
442
443 static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
444 int keytype)
445 {
446 EVP_PKEY *pkey = key;
447 ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
448
449 if (ecx == NULL) {
450 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
451 return 0;
452 }
453
454 if (!ecx_key_fromdata(ecx, params, 1)
455 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
456 ecx_key_free(ecx);
457 return 0;
458 }
459 return 1;
460 }
461
462 static int x25519_import_from(const OSSL_PARAM params[], void *key)
463 {
464 return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
465 }
466
467 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
468 EVP_PKEY_X25519,
469 EVP_PKEY_X25519,
470 0,
471 "X25519",
472 "OpenSSL X25519 algorithm",
473
474 ecx_pub_decode,
475 ecx_pub_encode,
476 ecx_pub_cmp,
477 ecx_pub_print,
478
479 ecx_priv_decode,
480 ecx_priv_encode,
481 ecx_priv_print,
482
483 ecx_size,
484 ecx_bits,
485 ecx_security_bits,
486
487 0, 0, 0, 0,
488 ecx_cmp_parameters,
489 0, 0,
490
491 ecx_free,
492 ecx_ctrl,
493 NULL,
494 NULL,
495
496 NULL,
497 NULL,
498 NULL,
499
500 NULL,
501 NULL,
502 NULL,
503
504 ecx_set_priv_key,
505 ecx_set_pub_key,
506 ecx_get_priv_key,
507 ecx_get_pub_key,
508 ecx_pkey_dirty_cnt,
509 ecx_pkey_export_to,
510 x25519_import_from
511 };
512
513 static int x448_import_from(const OSSL_PARAM params[], void *key)
514 {
515 return ecx_generic_import_from(params, key, EVP_PKEY_X448);
516 }
517
518 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
519 EVP_PKEY_X448,
520 EVP_PKEY_X448,
521 0,
522 "X448",
523 "OpenSSL X448 algorithm",
524
525 ecx_pub_decode,
526 ecx_pub_encode,
527 ecx_pub_cmp,
528 ecx_pub_print,
529
530 ecx_priv_decode,
531 ecx_priv_encode,
532 ecx_priv_print,
533
534 ecx_size,
535 ecx_bits,
536 ecx_security_bits,
537
538 0, 0, 0, 0,
539 ecx_cmp_parameters,
540 0, 0,
541
542 ecx_free,
543 ecx_ctrl,
544 NULL,
545 NULL,
546
547 NULL,
548 NULL,
549 NULL,
550
551 NULL,
552 NULL,
553 NULL,
554
555 ecx_set_priv_key,
556 ecx_set_pub_key,
557 ecx_get_priv_key,
558 ecx_get_pub_key,
559 ecx_pkey_dirty_cnt,
560 ecx_pkey_export_to,
561 x448_import_from
562 };
563
564 static int ecd_size25519(const EVP_PKEY *pkey)
565 {
566 return ED25519_SIGSIZE;
567 }
568
569 static int ecd_size448(const EVP_PKEY *pkey)
570 {
571 return ED448_SIGSIZE;
572 }
573
574 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
575 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
576 EVP_PKEY *pkey)
577 {
578 const ASN1_OBJECT *obj;
579 int ptype;
580 int nid;
581
582 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
583 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
584 nid = OBJ_obj2nid(obj);
585 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
586 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
587 return 0;
588 }
589
590 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
591 return 0;
592
593 return 2;
594 }
595
596 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
597 X509_ALGOR *alg1, X509_ALGOR *alg2,
598 ASN1_BIT_STRING *str)
599 {
600 /* Set algorithms identifiers */
601 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
602 if (alg2)
603 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
604 /* Algorithm identifiers set: carry on as normal */
605 return 3;
606 }
607
608 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
609 const ASN1_STRING *sig)
610 {
611 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
612 X509_SIG_INFO_TLS);
613 return 1;
614 }
615
616 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
617 X509_ALGOR *alg1, X509_ALGOR *alg2,
618 ASN1_BIT_STRING *str)
619 {
620 /* Set algorithm identifier */
621 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
622 if (alg2 != NULL)
623 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
624 /* Algorithm identifier set: carry on as normal */
625 return 3;
626 }
627
628 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
629 const ASN1_STRING *sig)
630 {
631 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
632 X509_SIG_INFO_TLS);
633 return 1;
634 }
635
636 static int ed25519_import_from(const OSSL_PARAM params[], void *key)
637 {
638 return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
639 }
640
641 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
642 EVP_PKEY_ED25519,
643 EVP_PKEY_ED25519,
644 0,
645 "ED25519",
646 "OpenSSL ED25519 algorithm",
647
648 ecx_pub_decode,
649 ecx_pub_encode,
650 ecx_pub_cmp,
651 ecx_pub_print,
652
653 ecx_priv_decode,
654 ecx_priv_encode,
655 ecx_priv_print,
656
657 ecd_size25519,
658 ecx_bits,
659 ecx_security_bits,
660
661 0, 0, 0, 0,
662 ecx_cmp_parameters,
663 0, 0,
664
665 ecx_free,
666 ecd_ctrl,
667 NULL,
668 NULL,
669 ecd_item_verify,
670 ecd_item_sign25519,
671 ecd_sig_info_set25519,
672
673 NULL,
674 NULL,
675 NULL,
676
677 ecx_set_priv_key,
678 ecx_set_pub_key,
679 ecx_get_priv_key,
680 ecx_get_pub_key,
681 ecx_pkey_dirty_cnt,
682 ecx_pkey_export_to,
683 ed25519_import_from
684 };
685
686 static int ed448_import_from(const OSSL_PARAM params[], void *key)
687 {
688 return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
689 }
690
691 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
692 EVP_PKEY_ED448,
693 EVP_PKEY_ED448,
694 0,
695 "ED448",
696 "OpenSSL ED448 algorithm",
697
698 ecx_pub_decode,
699 ecx_pub_encode,
700 ecx_pub_cmp,
701 ecx_pub_print,
702
703 ecx_priv_decode,
704 ecx_priv_encode,
705 ecx_priv_print,
706
707 ecd_size448,
708 ecx_bits,
709 ecx_security_bits,
710
711 0, 0, 0, 0,
712 ecx_cmp_parameters,
713 0, 0,
714
715 ecx_free,
716 ecd_ctrl,
717 NULL,
718 NULL,
719 ecd_item_verify,
720 ecd_item_sign448,
721 ecd_sig_info_set448,
722
723 NULL,
724 NULL,
725 NULL,
726
727 ecx_set_priv_key,
728 ecx_set_pub_key,
729 ecx_get_priv_key,
730 ecx_get_pub_key,
731 ecx_pkey_dirty_cnt,
732 ecx_pkey_export_to,
733 ed448_import_from
734 };
735
736 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
737 {
738 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
739 }
740
741 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
742 size_t *keylen,
743 const unsigned char **privkey,
744 const unsigned char **pubkey)
745 {
746 const ECX_KEY *ecxkey, *peerkey;
747
748 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
749 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
750 return 0;
751 }
752 ecxkey = ctx->pkey->pkey.ecx;
753 peerkey = ctx->peerkey->pkey.ecx;
754 if (ecxkey == NULL || ecxkey->privkey == NULL) {
755 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
756 return 0;
757 }
758 if (peerkey == NULL) {
759 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
760 return 0;
761 }
762 *privkey = ecxkey->privkey;
763 *pubkey = peerkey->pubkey;
764
765 return 1;
766 }
767
768 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
769 size_t *keylen)
770 {
771 const unsigned char *privkey, *pubkey;
772
773 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
774 || (key != NULL
775 && X25519(key, privkey, pubkey) == 0))
776 return 0;
777 *keylen = X25519_KEYLEN;
778 return 1;
779 }
780
781 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
782 size_t *keylen)
783 {
784 const unsigned char *privkey, *pubkey;
785
786 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
787 || (key != NULL
788 && X448(key, privkey, pubkey) == 0))
789 return 0;
790 *keylen = X448_KEYLEN;
791 return 1;
792 }
793
794 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
795 {
796 /* Only need to handle peer key for derivation */
797 if (type == EVP_PKEY_CTRL_PEER_KEY)
798 return 1;
799 return -2;
800 }
801
802 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
803 EVP_PKEY_X25519,
804 0, 0, 0, 0, 0, 0, 0,
805 pkey_ecx_keygen,
806 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
807 pkey_ecx_derive25519,
808 pkey_ecx_ctrl,
809 0
810 };
811
812 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
813 EVP_PKEY_X448,
814 0, 0, 0, 0, 0, 0, 0,
815 pkey_ecx_keygen,
816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
817 pkey_ecx_derive448,
818 pkey_ecx_ctrl,
819 0
820 };
821
822 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
823 size_t *siglen, const unsigned char *tbs,
824 size_t tbslen)
825 {
826 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
827
828 if (sig == NULL) {
829 *siglen = ED25519_SIGSIZE;
830 return 1;
831 }
832 if (*siglen < ED25519_SIGSIZE) {
833 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
834 return 0;
835 }
836
837 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
838 return 0;
839 *siglen = ED25519_SIGSIZE;
840 return 1;
841 }
842
843 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
844 size_t *siglen, const unsigned char *tbs,
845 size_t tbslen)
846 {
847 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
848
849 if (sig == NULL) {
850 *siglen = ED448_SIGSIZE;
851 return 1;
852 }
853 if (*siglen < ED448_SIGSIZE) {
854 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
855 return 0;
856 }
857
858 /*
859 * TODO(3.0): We use NULL for the library context for now. Will need to
860 * change later.
861 */
862 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
863 NULL, 0) == 0)
864 return 0;
865 *siglen = ED448_SIGSIZE;
866 return 1;
867 }
868
869 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
870 size_t siglen, const unsigned char *tbs,
871 size_t tbslen)
872 {
873 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
874
875 if (siglen != ED25519_SIGSIZE)
876 return 0;
877
878 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
879 }
880
881 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
882 size_t siglen, const unsigned char *tbs,
883 size_t tbslen)
884 {
885 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
886
887 if (siglen != ED448_SIGSIZE)
888 return 0;
889
890 /*
891 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
892 * change.
893 */
894 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
895 }
896
897 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
898 {
899 switch (type) {
900 case EVP_PKEY_CTRL_MD:
901 /* Only NULL allowed as digest */
902 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
903 return 1;
904 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
905 return 0;
906
907 case EVP_PKEY_CTRL_DIGESTINIT:
908 return 1;
909 }
910 return -2;
911 }
912
913 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
914 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
915 0, 0, 0, 0, 0, 0,
916 pkey_ecx_keygen,
917 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
918 pkey_ecd_ctrl,
919 0,
920 pkey_ecd_digestsign25519,
921 pkey_ecd_digestverify25519
922 };
923
924 static const EVP_PKEY_METHOD ed448_pkey_meth = {
925 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
926 0, 0, 0, 0, 0, 0,
927 pkey_ecx_keygen,
928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
929 pkey_ecd_ctrl,
930 0,
931 pkey_ecd_digestsign448,
932 pkey_ecd_digestverify448
933 };
934
935 #ifdef S390X_EC_ASM
936 # include "s390x_arch.h"
937 # include "internal/constant_time.h"
938
939 static void s390x_x25519_mod_p(unsigned char u[32])
940 {
941 unsigned char u_red[32];
942 unsigned int c = 0;
943 int i;
944
945 memcpy(u_red, u, sizeof(u_red));
946
947 c += (unsigned int)u_red[31] + 19;
948 u_red[31] = (unsigned char)c;
949 c >>= 8;
950
951 for (i = 30; i >= 0; i--) {
952 c += (unsigned int)u_red[i];
953 u_red[i] = (unsigned char)c;
954 c >>= 8;
955 }
956
957 c = (u_red[0] & 0x80) >> 7;
958 u_red[0] &= 0x7f;
959 constant_time_cond_swap_buff(0 - (unsigned char)c,
960 u, u_red, sizeof(u_red));
961 }
962
963 static void s390x_x448_mod_p(unsigned char u[56])
964 {
965 unsigned char u_red[56];
966 unsigned int c = 0;
967 int i;
968
969 memcpy(u_red, u, sizeof(u_red));
970
971 c += (unsigned int)u_red[55] + 1;
972 u_red[55] = (unsigned char)c;
973 c >>= 8;
974
975 for (i = 54; i >= 28; i--) {
976 c += (unsigned int)u_red[i];
977 u_red[i] = (unsigned char)c;
978 c >>= 8;
979 }
980
981 c += (unsigned int)u_red[27] + 1;
982 u_red[27] = (unsigned char)c;
983 c >>= 8;
984
985 for (i = 26; i >= 0; i--) {
986 c += (unsigned int)u_red[i];
987 u_red[i] = (unsigned char)c;
988 c >>= 8;
989 }
990
991 constant_time_cond_swap_buff(0 - (unsigned char)c,
992 u, u_red, sizeof(u_red));
993 }
994
995 int s390x_x25519_mul(unsigned char u_dst[32],
996 const unsigned char u_src[32],
997 const unsigned char d_src[32])
998 {
999 union {
1000 struct {
1001 unsigned char u_dst[32];
1002 unsigned char u_src[32];
1003 unsigned char d_src[32];
1004 } x25519;
1005 unsigned long long buff[512];
1006 } param;
1007 int rc;
1008
1009 memset(&param, 0, sizeof(param));
1010
1011 s390x_flip_endian32(param.x25519.u_src, u_src);
1012 param.x25519.u_src[0] &= 0x7f;
1013 s390x_x25519_mod_p(param.x25519.u_src);
1014
1015 s390x_flip_endian32(param.x25519.d_src, d_src);
1016 param.x25519.d_src[31] &= 248;
1017 param.x25519.d_src[0] &= 127;
1018 param.x25519.d_src[0] |= 64;
1019
1020 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, &param.x25519) ? 0 : 1;
1021 if (rc == 1)
1022 s390x_flip_endian32(u_dst, param.x25519.u_dst);
1023
1024 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
1025 return rc;
1026 }
1027
1028 int s390x_x448_mul(unsigned char u_dst[56],
1029 const unsigned char u_src[56],
1030 const unsigned char d_src[56])
1031 {
1032 union {
1033 struct {
1034 unsigned char u_dst[64];
1035 unsigned char u_src[64];
1036 unsigned char d_src[64];
1037 } x448;
1038 unsigned long long buff[512];
1039 } param;
1040 int rc;
1041
1042 memset(&param, 0, sizeof(param));
1043
1044 memcpy(param.x448.u_src, u_src, 56);
1045 memcpy(param.x448.d_src, d_src, 56);
1046
1047 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1048 s390x_x448_mod_p(param.x448.u_src + 8);
1049
1050 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1051 param.x448.d_src[63] &= 252;
1052 param.x448.d_src[8] |= 128;
1053
1054 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, &param.x448) ? 0 : 1;
1055 if (rc == 1) {
1056 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1057 memcpy(u_dst, param.x448.u_dst, 56);
1058 }
1059
1060 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1061 return rc;
1062 }
1063
1064 static int s390x_ed25519_mul(unsigned char x_dst[32],
1065 unsigned char y_dst[32],
1066 const unsigned char x_src[32],
1067 const unsigned char y_src[32],
1068 const unsigned char d_src[32])
1069 {
1070 union {
1071 struct {
1072 unsigned char x_dst[32];
1073 unsigned char y_dst[32];
1074 unsigned char x_src[32];
1075 unsigned char y_src[32];
1076 unsigned char d_src[32];
1077 } ed25519;
1078 unsigned long long buff[512];
1079 } param;
1080 int rc;
1081
1082 memset(&param, 0, sizeof(param));
1083
1084 s390x_flip_endian32(param.ed25519.x_src, x_src);
1085 s390x_flip_endian32(param.ed25519.y_src, y_src);
1086 s390x_flip_endian32(param.ed25519.d_src, d_src);
1087
1088 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, &param.ed25519) ? 0 : 1;
1089 if (rc == 1) {
1090 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1091 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1092 }
1093
1094 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1095 return rc;
1096 }
1097
1098 static int s390x_ed448_mul(unsigned char x_dst[57],
1099 unsigned char y_dst[57],
1100 const unsigned char x_src[57],
1101 const unsigned char y_src[57],
1102 const unsigned char d_src[57])
1103 {
1104 union {
1105 struct {
1106 unsigned char x_dst[64];
1107 unsigned char y_dst[64];
1108 unsigned char x_src[64];
1109 unsigned char y_src[64];
1110 unsigned char d_src[64];
1111 } ed448;
1112 unsigned long long buff[512];
1113 } param;
1114 int rc;
1115
1116 memset(&param, 0, sizeof(param));
1117
1118 memcpy(param.ed448.x_src, x_src, 57);
1119 memcpy(param.ed448.y_src, y_src, 57);
1120 memcpy(param.ed448.d_src, d_src, 57);
1121 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1122 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1123 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1124
1125 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, &param.ed448) ? 0 : 1;
1126 if (rc == 1) {
1127 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1128 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1129 memcpy(x_dst, param.ed448.x_dst, 57);
1130 memcpy(y_dst, param.ed448.y_dst, 57);
1131 }
1132
1133 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1134 return rc;
1135 }
1136
1137 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1138 {
1139 static const unsigned char generator[] = {
1140 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1143 };
1144 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
1145 unsigned char *privkey = NULL, *pubkey;
1146
1147 if (key == NULL) {
1148 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1149 goto err;
1150 }
1151
1152 pubkey = key->pubkey;
1153
1154 privkey = ecx_key_allocate_privkey(key);
1155 if (privkey == NULL) {
1156 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1157 goto err;
1158 }
1159
1160 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1161 goto err;
1162
1163 privkey[0] &= 248;
1164 privkey[31] &= 127;
1165 privkey[31] |= 64;
1166
1167 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1168 goto err;
1169
1170 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1171 return 1;
1172 err:
1173 ecx_key_free(key);
1174 return 0;
1175 }
1176
1177 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1178 {
1179 static const unsigned char generator[] = {
1180 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1185 };
1186 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1187 unsigned char *privkey = NULL, *pubkey;
1188
1189 if (key == NULL) {
1190 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1191 goto err;
1192 }
1193
1194 pubkey = key->pubkey;
1195
1196 privkey = ecx_key_allocate_privkey(key);
1197 if (privkey == NULL) {
1198 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1199 goto err;
1200 }
1201
1202 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1203 goto err;
1204
1205 privkey[0] &= 252;
1206 privkey[55] |= 128;
1207
1208 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1209 goto err;
1210
1211 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1212 return 1;
1213 err:
1214 ecx_key_free(key);
1215 return 0;
1216 }
1217
1218 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1219 {
1220 static const unsigned char generator_x[] = {
1221 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1222 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1223 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1224 };
1225 static const unsigned char generator_y[] = {
1226 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1227 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1228 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1229 };
1230 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1231 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1232 unsigned char *privkey = NULL, *pubkey;
1233 unsigned int sz;
1234
1235 if (key == NULL) {
1236 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1237 goto err;
1238 }
1239
1240 pubkey = key->pubkey;
1241
1242 privkey = ecx_key_allocate_privkey(key);
1243 if (privkey == NULL) {
1244 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1245 goto err;
1246 }
1247
1248 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1249 goto err;
1250
1251 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1252 goto err;
1253
1254 buff[0] &= 248;
1255 buff[31] &= 63;
1256 buff[31] |= 64;
1257
1258 if (s390x_ed25519_mul(x_dst, pubkey,
1259 generator_x, generator_y, buff) != 1)
1260 goto err;
1261
1262 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1263
1264 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1265 return 1;
1266 err:
1267 ecx_key_free(key);
1268 return 0;
1269 }
1270
1271 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1272 {
1273 static const unsigned char generator_x[] = {
1274 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1275 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1276 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1277 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1278 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1279 };
1280 static const unsigned char generator_y[] = {
1281 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1282 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1283 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1284 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1285 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1286 };
1287 unsigned char x_dst[57], buff[114];
1288 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1289 unsigned char *privkey = NULL, *pubkey;
1290 EVP_MD_CTX *hashctx = NULL;
1291
1292 if (key == NULL) {
1293 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1294 goto err;
1295 }
1296
1297 pubkey = key->pubkey;
1298
1299 privkey = ecx_key_allocate_privkey(key);
1300 if (privkey == NULL) {
1301 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1302 goto err;
1303 }
1304
1305 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1306 goto err;
1307
1308 hashctx = EVP_MD_CTX_new();
1309 if (hashctx == NULL)
1310 goto err;
1311 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1312 goto err;
1313 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1314 goto err;
1315 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1316 goto err;
1317
1318 buff[0] &= -4;
1319 buff[55] |= 0x80;
1320 buff[56] = 0;
1321
1322 if (s390x_ed448_mul(x_dst, pubkey,
1323 generator_x, generator_y, buff) != 1)
1324 goto err;
1325
1326 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1327
1328 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1329 EVP_MD_CTX_free(hashctx);
1330 return 1;
1331 err:
1332 ecx_key_free(key);
1333 EVP_MD_CTX_free(hashctx);
1334 return 0;
1335 }
1336
1337 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1338 size_t *keylen)
1339 {
1340 const unsigned char *privkey, *pubkey;
1341
1342 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1343 return 0;
1344
1345 if (key != NULL)
1346 return s390x_x25519_mul(key, pubkey, privkey);
1347
1348 *keylen = X25519_KEYLEN;
1349 return 1;
1350 }
1351
1352 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1353 size_t *keylen)
1354 {
1355 const unsigned char *privkey, *pubkey;
1356
1357 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1358 return 0;
1359
1360 if (key != NULL)
1361 return s390x_x448_mul(key, pubkey, privkey);
1362
1363 *keylen = X448_KEYLEN;
1364 return 1;
1365 }
1366
1367 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1368 unsigned char *sig, size_t *siglen,
1369 const unsigned char *tbs,
1370 size_t tbslen)
1371 {
1372 union {
1373 struct {
1374 unsigned char sig[64];
1375 unsigned char priv[32];
1376 } ed25519;
1377 unsigned long long buff[512];
1378 } param;
1379 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1380 int rc;
1381
1382 if (sig == NULL) {
1383 *siglen = ED25519_SIGSIZE;
1384 return 1;
1385 }
1386
1387 if (*siglen < ED25519_SIGSIZE) {
1388 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1389 return 0;
1390 }
1391
1392 memset(&param, 0, sizeof(param));
1393 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1394
1395 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
1396 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1397 if (rc != 0)
1398 return 0;
1399
1400 s390x_flip_endian32(sig, param.ed25519.sig);
1401 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1402
1403 *siglen = ED25519_SIGSIZE;
1404 return 1;
1405 }
1406
1407 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1408 unsigned char *sig, size_t *siglen,
1409 const unsigned char *tbs,
1410 size_t tbslen)
1411 {
1412 union {
1413 struct {
1414 unsigned char sig[128];
1415 unsigned char priv[64];
1416 } ed448;
1417 unsigned long long buff[512];
1418 } param;
1419 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1420 int rc;
1421
1422 if (sig == NULL) {
1423 *siglen = ED448_SIGSIZE;
1424 return 1;
1425 }
1426
1427 if (*siglen < ED448_SIGSIZE) {
1428 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1429 return 0;
1430 }
1431
1432 memset(&param, 0, sizeof(param));
1433 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1434
1435 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
1436 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1437 if (rc != 0)
1438 return 0;
1439
1440 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1441 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1442 memcpy(sig, param.ed448.sig, 57);
1443 memcpy(sig + 57, param.ed448.sig + 64, 57);
1444
1445 *siglen = ED448_SIGSIZE;
1446 return 1;
1447 }
1448
1449 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1450 const unsigned char *sig,
1451 size_t siglen,
1452 const unsigned char *tbs,
1453 size_t tbslen)
1454 {
1455 union {
1456 struct {
1457 unsigned char sig[64];
1458 unsigned char pub[32];
1459 } ed25519;
1460 unsigned long long buff[512];
1461 } param;
1462 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1463
1464 if (siglen != ED25519_SIGSIZE)
1465 return 0;
1466
1467 memset(&param, 0, sizeof(param));
1468 s390x_flip_endian32(param.ed25519.sig, sig);
1469 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1470 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1471
1472 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1473 &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1474 }
1475
1476 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1477 const unsigned char *sig,
1478 size_t siglen,
1479 const unsigned char *tbs,
1480 size_t tbslen)
1481 {
1482 union {
1483 struct {
1484 unsigned char sig[128];
1485 unsigned char pub[64];
1486 } ed448;
1487 unsigned long long buff[512];
1488 } param;
1489 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1490
1491 if (siglen != ED448_SIGSIZE)
1492 return 0;
1493
1494 memset(&param, 0, sizeof(param));
1495 memcpy(param.ed448.sig, sig, 57);
1496 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1497 memcpy(param.ed448.sig + 64, sig + 57, 57);
1498 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1499 memcpy(param.ed448.pub, edkey->pubkey, 57);
1500 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1501
1502 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1503 &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
1504 }
1505
1506 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1507 EVP_PKEY_X25519,
1508 0, 0, 0, 0, 0, 0, 0,
1509 s390x_pkey_ecx_keygen25519,
1510 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1511 s390x_pkey_ecx_derive25519,
1512 pkey_ecx_ctrl,
1513 0
1514 };
1515
1516 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1517 EVP_PKEY_X448,
1518 0, 0, 0, 0, 0, 0, 0,
1519 s390x_pkey_ecx_keygen448,
1520 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1521 s390x_pkey_ecx_derive448,
1522 pkey_ecx_ctrl,
1523 0
1524 };
1525 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1526 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1527 0, 0, 0, 0, 0, 0,
1528 s390x_pkey_ecd_keygen25519,
1529 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1530 pkey_ecd_ctrl,
1531 0,
1532 s390x_pkey_ecd_digestsign25519,
1533 s390x_pkey_ecd_digestverify25519
1534 };
1535
1536 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1537 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1538 0, 0, 0, 0, 0, 0,
1539 s390x_pkey_ecd_keygen448,
1540 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1541 pkey_ecd_ctrl,
1542 0,
1543 s390x_pkey_ecd_digestsign448,
1544 s390x_pkey_ecd_digestverify448
1545 };
1546 #endif
1547
1548 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1549 {
1550 #ifdef S390X_EC_ASM
1551 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1552 return &ecx25519_s390x_pkey_meth;
1553 #endif
1554 return &ecx25519_pkey_meth;
1555 }
1556
1557 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1558 {
1559 #ifdef S390X_EC_ASM
1560 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1561 return &ecx448_s390x_pkey_meth;
1562 #endif
1563 return &ecx448_pkey_meth;
1564 }
1565
1566 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1567 {
1568 #ifdef S390X_EC_ASM
1569 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1570 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1571 && OPENSSL_s390xcap_P.kdsa[0]
1572 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1573 return &ed25519_s390x_pkey_meth;
1574 #endif
1575 return &ed25519_pkey_meth;
1576 }
1577
1578 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1579 {
1580 #ifdef S390X_EC_ASM
1581 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1582 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1583 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1584 return &ed448_s390x_pkey_meth;
1585 #endif
1586 return &ed448_pkey_meth;
1587 }