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