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