ecx_meth.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. /*
  2. * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (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. #include <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/x509.h>
  12. #include <openssl/ec.h>
  13. #include <openssl/rand.h>
  14. #include "crypto/asn1.h"
  15. #include "crypto/evp.h"
  16. #include "ec_local.h"
  17. #include "curve448/curve448_local.h"
  18. #define X25519_BITS 253
  19. #define X25519_SECURITY_BITS 128
  20. #define ED25519_SIGSIZE 64
  21. #define X448_BITS 448
  22. #define ED448_BITS 456
  23. #define X448_SECURITY_BITS 224
  24. #define ED448_SIGSIZE 114
  25. #define ISX448(id) ((id) == EVP_PKEY_X448)
  26. #define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
  27. #define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
  28. : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
  29. : ED448_KEYLEN))
  30. #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
  31. typedef enum {
  32. KEY_OP_PUBLIC,
  33. KEY_OP_PRIVATE,
  34. KEY_OP_KEYGEN
  35. } ecx_key_op_t;
  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. if (op != KEY_OP_KEYGEN) {
  43. if (palg != NULL) {
  44. int ptype;
  45. /* Algorithm parameters must be absent */
  46. X509_ALGOR_get0(NULL, &ptype, NULL, palg);
  47. if (ptype != V_ASN1_UNDEF) {
  48. ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
  49. return 0;
  50. }
  51. }
  52. if (p == NULL || plen != KEYLENID(id)) {
  53. ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
  54. return 0;
  55. }
  56. }
  57. key = OPENSSL_zalloc(sizeof(*key));
  58. if (key == NULL) {
  59. ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
  60. return 0;
  61. }
  62. pubkey = key->pubkey;
  63. if (op == KEY_OP_PUBLIC) {
  64. memcpy(pubkey, p, plen);
  65. } else {
  66. privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
  67. if (privkey == NULL) {
  68. ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
  69. goto err;
  70. }
  71. if (op == KEY_OP_KEYGEN) {
  72. if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
  73. OPENSSL_secure_free(privkey);
  74. key->privkey = NULL;
  75. goto err;
  76. }
  77. if (id == EVP_PKEY_X25519) {
  78. privkey[0] &= 248;
  79. privkey[X25519_KEYLEN - 1] &= 127;
  80. privkey[X25519_KEYLEN - 1] |= 64;
  81. } else if (id == EVP_PKEY_X448) {
  82. privkey[0] &= 252;
  83. privkey[X448_KEYLEN - 1] |= 128;
  84. }
  85. } else {
  86. memcpy(privkey, p, KEYLENID(id));
  87. }
  88. switch (id) {
  89. case EVP_PKEY_X25519:
  90. X25519_public_from_private(pubkey, privkey);
  91. break;
  92. case EVP_PKEY_ED25519:
  93. ED25519_public_from_private(pubkey, privkey);
  94. break;
  95. case EVP_PKEY_X448:
  96. X448_public_from_private(pubkey, privkey);
  97. break;
  98. case EVP_PKEY_ED448:
  99. ED448_public_from_private(pubkey, privkey);
  100. break;
  101. }
  102. }
  103. EVP_PKEY_assign(pkey, id, key);
  104. return 1;
  105. err:
  106. OPENSSL_free(key);
  107. return 0;
  108. }
  109. static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
  110. {
  111. const ECX_KEY *ecxkey = pkey->pkey.ecx;
  112. unsigned char *penc;
  113. if (ecxkey == NULL) {
  114. ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
  115. return 0;
  116. }
  117. penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
  118. if (penc == NULL) {
  119. ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
  120. return 0;
  121. }
  122. if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
  123. V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
  124. OPENSSL_free(penc);
  125. ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
  126. return 0;
  127. }
  128. return 1;
  129. }
  130. static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
  131. {
  132. const unsigned char *p;
  133. int pklen;
  134. X509_ALGOR *palg;
  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);
  139. }
  140. static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
  141. {
  142. const ECX_KEY *akey = a->pkey.ecx;
  143. const ECX_KEY *bkey = b->pkey.ecx;
  144. if (akey == NULL || bkey == NULL)
  145. return -2;
  146. return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
  147. }
  148. static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
  149. {
  150. const unsigned char *p;
  151. int plen;
  152. ASN1_OCTET_STRING *oct = NULL;
  153. const X509_ALGOR *palg;
  154. int rv;
  155. if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
  156. return 0;
  157. oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
  158. if (oct == NULL) {
  159. p = NULL;
  160. plen = 0;
  161. } else {
  162. p = ASN1_STRING_get0_data(oct);
  163. plen = ASN1_STRING_length(oct);
  164. }
  165. rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
  166. ASN1_STRING_clear_free(oct);
  167. return rv;
  168. }
  169. static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
  170. {
  171. const ECX_KEY *ecxkey = pkey->pkey.ecx;
  172. ASN1_OCTET_STRING oct;
  173. unsigned char *penc = NULL;
  174. int penclen;
  175. if (ecxkey == NULL || ecxkey->privkey == NULL) {
  176. ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
  177. return 0;
  178. }
  179. oct.data = ecxkey->privkey;
  180. oct.length = KEYLEN(pkey);
  181. oct.flags = 0;
  182. penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
  183. if (penclen < 0) {
  184. ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
  185. return 0;
  186. }
  187. if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
  188. V_ASN1_UNDEF, NULL, penc, penclen)) {
  189. OPENSSL_clear_free(penc, penclen);
  190. ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
  191. return 0;
  192. }
  193. return 1;
  194. }
  195. static int ecx_size(const EVP_PKEY *pkey)
  196. {
  197. return KEYLEN(pkey);
  198. }
  199. static int ecx_bits(const EVP_PKEY *pkey)
  200. {
  201. if (IS25519(pkey->ameth->pkey_id)) {
  202. return X25519_BITS;
  203. } else if(ISX448(pkey->ameth->pkey_id)) {
  204. return X448_BITS;
  205. } else {
  206. return ED448_BITS;
  207. }
  208. }
  209. static int ecx_security_bits(const EVP_PKEY *pkey)
  210. {
  211. if (IS25519(pkey->ameth->pkey_id)) {
  212. return X25519_SECURITY_BITS;
  213. } else {
  214. return X448_SECURITY_BITS;
  215. }
  216. }
  217. static void ecx_free(EVP_PKEY *pkey)
  218. {
  219. if (pkey->pkey.ecx != NULL)
  220. OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey));
  221. OPENSSL_free(pkey->pkey.ecx);
  222. }
  223. /* "parameters" are always equal */
  224. static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
  225. {
  226. return 1;
  227. }
  228. static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  229. ASN1_PCTX *ctx, ecx_key_op_t op)
  230. {
  231. const ECX_KEY *ecxkey = pkey->pkey.ecx;
  232. const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
  233. if (op == KEY_OP_PRIVATE) {
  234. if (ecxkey == NULL || ecxkey->privkey == NULL) {
  235. if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
  236. return 0;
  237. return 1;
  238. }
  239. if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
  240. return 0;
  241. if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
  242. return 0;
  243. if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
  244. indent + 4) == 0)
  245. return 0;
  246. } else {
  247. if (ecxkey == NULL) {
  248. if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
  249. return 0;
  250. return 1;
  251. }
  252. if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
  253. return 0;
  254. }
  255. if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
  256. return 0;
  257. if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
  258. indent + 4) == 0)
  259. return 0;
  260. return 1;
  261. }
  262. static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  263. ASN1_PCTX *ctx)
  264. {
  265. return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
  266. }
  267. static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  268. ASN1_PCTX *ctx)
  269. {
  270. return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
  271. }
  272. static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  273. {
  274. switch (op) {
  275. case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
  276. return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
  277. KEY_OP_PUBLIC);
  278. case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
  279. if (pkey->pkey.ecx != NULL) {
  280. unsigned char **ppt = arg2;
  281. *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
  282. if (*ppt != NULL)
  283. return KEYLEN(pkey);
  284. }
  285. return 0;
  286. default:
  287. return -2;
  288. }
  289. }
  290. static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  291. {
  292. switch (op) {
  293. case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
  294. /* We currently only support Pure EdDSA which takes no digest */
  295. *(int *)arg2 = NID_undef;
  296. return 2;
  297. default:
  298. return -2;
  299. }
  300. }
  301. static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
  302. size_t len)
  303. {
  304. return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
  305. KEY_OP_PRIVATE);
  306. }
  307. static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
  308. {
  309. return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
  310. KEY_OP_PUBLIC);
  311. }
  312. static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
  313. size_t *len)
  314. {
  315. const ECX_KEY *key = pkey->pkey.ecx;
  316. if (priv == NULL) {
  317. *len = KEYLENID(pkey->ameth->pkey_id);
  318. return 1;
  319. }
  320. if (key == NULL
  321. || key->privkey == NULL
  322. || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
  323. return 0;
  324. *len = KEYLENID(pkey->ameth->pkey_id);
  325. memcpy(priv, key->privkey, *len);
  326. return 1;
  327. }
  328. static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
  329. size_t *len)
  330. {
  331. const ECX_KEY *key = pkey->pkey.ecx;
  332. if (pub == NULL) {
  333. *len = KEYLENID(pkey->ameth->pkey_id);
  334. return 1;
  335. }
  336. if (key == NULL
  337. || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
  338. return 0;
  339. *len = KEYLENID(pkey->ameth->pkey_id);
  340. memcpy(pub, key->pubkey, *len);
  341. return 1;
  342. }
  343. const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
  344. EVP_PKEY_X25519,
  345. EVP_PKEY_X25519,
  346. 0,
  347. "X25519",
  348. "OpenSSL X25519 algorithm",
  349. ecx_pub_decode,
  350. ecx_pub_encode,
  351. ecx_pub_cmp,
  352. ecx_pub_print,
  353. ecx_priv_decode,
  354. ecx_priv_encode,
  355. ecx_priv_print,
  356. ecx_size,
  357. ecx_bits,
  358. ecx_security_bits,
  359. 0, 0, 0, 0,
  360. ecx_cmp_parameters,
  361. 0, 0,
  362. ecx_free,
  363. ecx_ctrl,
  364. NULL,
  365. NULL,
  366. NULL,
  367. NULL,
  368. NULL,
  369. NULL,
  370. NULL,
  371. NULL,
  372. ecx_set_priv_key,
  373. ecx_set_pub_key,
  374. ecx_get_priv_key,
  375. ecx_get_pub_key,
  376. };
  377. const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
  378. EVP_PKEY_X448,
  379. EVP_PKEY_X448,
  380. 0,
  381. "X448",
  382. "OpenSSL X448 algorithm",
  383. ecx_pub_decode,
  384. ecx_pub_encode,
  385. ecx_pub_cmp,
  386. ecx_pub_print,
  387. ecx_priv_decode,
  388. ecx_priv_encode,
  389. ecx_priv_print,
  390. ecx_size,
  391. ecx_bits,
  392. ecx_security_bits,
  393. 0, 0, 0, 0,
  394. ecx_cmp_parameters,
  395. 0, 0,
  396. ecx_free,
  397. ecx_ctrl,
  398. NULL,
  399. NULL,
  400. NULL,
  401. NULL,
  402. NULL,
  403. NULL,
  404. NULL,
  405. NULL,
  406. ecx_set_priv_key,
  407. ecx_set_pub_key,
  408. ecx_get_priv_key,
  409. ecx_get_pub_key,
  410. };
  411. static int ecd_size25519(const EVP_PKEY *pkey)
  412. {
  413. return ED25519_SIGSIZE;
  414. }
  415. static int ecd_size448(const EVP_PKEY *pkey)
  416. {
  417. return ED448_SIGSIZE;
  418. }
  419. static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
  420. X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
  421. EVP_PKEY *pkey)
  422. {
  423. const ASN1_OBJECT *obj;
  424. int ptype;
  425. int nid;
  426. /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
  427. X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
  428. nid = OBJ_obj2nid(obj);
  429. if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
  430. ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
  431. return 0;
  432. }
  433. if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
  434. return 0;
  435. return 2;
  436. }
  437. static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
  438. X509_ALGOR *alg1, X509_ALGOR *alg2,
  439. ASN1_BIT_STRING *str)
  440. {
  441. /* Set algorithms identifiers */
  442. X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
  443. if (alg2)
  444. X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
  445. /* Algorithm identifiers set: carry on as normal */
  446. return 3;
  447. }
  448. static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
  449. const ASN1_STRING *sig)
  450. {
  451. X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
  452. X509_SIG_INFO_TLS);
  453. return 1;
  454. }
  455. static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
  456. X509_ALGOR *alg1, X509_ALGOR *alg2,
  457. ASN1_BIT_STRING *str)
  458. {
  459. /* Set algorithm identifier */
  460. X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
  461. if (alg2 != NULL)
  462. X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
  463. /* Algorithm identifier set: carry on as normal */
  464. return 3;
  465. }
  466. static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
  467. const ASN1_STRING *sig)
  468. {
  469. X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
  470. X509_SIG_INFO_TLS);
  471. return 1;
  472. }
  473. const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
  474. EVP_PKEY_ED25519,
  475. EVP_PKEY_ED25519,
  476. 0,
  477. "ED25519",
  478. "OpenSSL ED25519 algorithm",
  479. ecx_pub_decode,
  480. ecx_pub_encode,
  481. ecx_pub_cmp,
  482. ecx_pub_print,
  483. ecx_priv_decode,
  484. ecx_priv_encode,
  485. ecx_priv_print,
  486. ecd_size25519,
  487. ecx_bits,
  488. ecx_security_bits,
  489. 0, 0, 0, 0,
  490. ecx_cmp_parameters,
  491. 0, 0,
  492. ecx_free,
  493. ecd_ctrl,
  494. NULL,
  495. NULL,
  496. ecd_item_verify,
  497. ecd_item_sign25519,
  498. ecd_sig_info_set25519,
  499. NULL,
  500. NULL,
  501. NULL,
  502. ecx_set_priv_key,
  503. ecx_set_pub_key,
  504. ecx_get_priv_key,
  505. ecx_get_pub_key,
  506. };
  507. const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
  508. EVP_PKEY_ED448,
  509. EVP_PKEY_ED448,
  510. 0,
  511. "ED448",
  512. "OpenSSL ED448 algorithm",
  513. ecx_pub_decode,
  514. ecx_pub_encode,
  515. ecx_pub_cmp,
  516. ecx_pub_print,
  517. ecx_priv_decode,
  518. ecx_priv_encode,
  519. ecx_priv_print,
  520. ecd_size448,
  521. ecx_bits,
  522. ecx_security_bits,
  523. 0, 0, 0, 0,
  524. ecx_cmp_parameters,
  525. 0, 0,
  526. ecx_free,
  527. ecd_ctrl,
  528. NULL,
  529. NULL,
  530. ecd_item_verify,
  531. ecd_item_sign448,
  532. ecd_sig_info_set448,
  533. NULL,
  534. NULL,
  535. NULL,
  536. ecx_set_priv_key,
  537. ecx_set_pub_key,
  538. ecx_get_priv_key,
  539. ecx_get_pub_key,
  540. };
  541. static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
  542. {
  543. return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
  544. }
  545. static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
  546. size_t *keylen,
  547. const unsigned char **privkey,
  548. const unsigned char **pubkey)
  549. {
  550. const ECX_KEY *ecxkey, *peerkey;
  551. if (ctx->pkey == NULL || ctx->peerkey == NULL) {
  552. ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
  553. return 0;
  554. }
  555. ecxkey = ctx->pkey->pkey.ecx;
  556. peerkey = ctx->peerkey->pkey.ecx;
  557. if (ecxkey == NULL || ecxkey->privkey == NULL) {
  558. ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
  559. return 0;
  560. }
  561. if (peerkey == NULL) {
  562. ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
  563. return 0;
  564. }
  565. *privkey = ecxkey->privkey;
  566. *pubkey = peerkey->pubkey;
  567. return 1;
  568. }
  569. static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
  570. size_t *keylen)
  571. {
  572. const unsigned char *privkey, *pubkey;
  573. if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
  574. || (key != NULL
  575. && X25519(key, privkey, pubkey) == 0))
  576. return 0;
  577. *keylen = X25519_KEYLEN;
  578. return 1;
  579. }
  580. static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
  581. size_t *keylen)
  582. {
  583. const unsigned char *privkey, *pubkey;
  584. if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
  585. || (key != NULL
  586. && X448(key, privkey, pubkey) == 0))
  587. return 0;
  588. *keylen = X448_KEYLEN;
  589. return 1;
  590. }
  591. static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
  592. {
  593. /* Only need to handle peer key for derivation */
  594. if (type == EVP_PKEY_CTRL_PEER_KEY)
  595. return 1;
  596. return -2;
  597. }
  598. const EVP_PKEY_METHOD ecx25519_pkey_meth = {
  599. EVP_PKEY_X25519,
  600. 0, 0, 0, 0, 0, 0, 0,
  601. pkey_ecx_keygen,
  602. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  603. pkey_ecx_derive25519,
  604. pkey_ecx_ctrl,
  605. 0
  606. };
  607. const EVP_PKEY_METHOD ecx448_pkey_meth = {
  608. EVP_PKEY_X448,
  609. 0, 0, 0, 0, 0, 0, 0,
  610. pkey_ecx_keygen,
  611. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  612. pkey_ecx_derive448,
  613. pkey_ecx_ctrl,
  614. 0
  615. };
  616. static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
  617. size_t *siglen, const unsigned char *tbs,
  618. size_t tbslen)
  619. {
  620. const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
  621. if (sig == NULL) {
  622. *siglen = ED25519_SIGSIZE;
  623. return 1;
  624. }
  625. if (*siglen < ED25519_SIGSIZE) {
  626. ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
  627. return 0;
  628. }
  629. if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
  630. return 0;
  631. *siglen = ED25519_SIGSIZE;
  632. return 1;
  633. }
  634. static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
  635. size_t *siglen, const unsigned char *tbs,
  636. size_t tbslen)
  637. {
  638. const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
  639. if (sig == NULL) {
  640. *siglen = ED448_SIGSIZE;
  641. return 1;
  642. }
  643. if (*siglen < ED448_SIGSIZE) {
  644. ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
  645. return 0;
  646. }
  647. if (ED448_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
  648. 0) == 0)
  649. return 0;
  650. *siglen = ED448_SIGSIZE;
  651. return 1;
  652. }
  653. static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
  654. size_t siglen, const unsigned char *tbs,
  655. size_t tbslen)
  656. {
  657. const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
  658. if (siglen != ED25519_SIGSIZE)
  659. return 0;
  660. return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
  661. }
  662. static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
  663. size_t siglen, const unsigned char *tbs,
  664. size_t tbslen)
  665. {
  666. const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
  667. if (siglen != ED448_SIGSIZE)
  668. return 0;
  669. return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0);
  670. }
  671. static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
  672. {
  673. switch (type) {
  674. case EVP_PKEY_CTRL_MD:
  675. /* Only NULL allowed as digest */
  676. if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
  677. return 1;
  678. ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
  679. return 0;
  680. case EVP_PKEY_CTRL_DIGESTINIT:
  681. return 1;
  682. }
  683. return -2;
  684. }
  685. const EVP_PKEY_METHOD ed25519_pkey_meth = {
  686. EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
  687. 0, 0, 0, 0, 0, 0,
  688. pkey_ecx_keygen,
  689. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  690. pkey_ecd_ctrl,
  691. 0,
  692. pkey_ecd_digestsign25519,
  693. pkey_ecd_digestverify25519
  694. };
  695. const EVP_PKEY_METHOD ed448_pkey_meth = {
  696. EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
  697. 0, 0, 0, 0, 0, 0,
  698. pkey_ecx_keygen,
  699. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  700. pkey_ecd_ctrl,
  701. 0,
  702. pkey_ecd_digestsign448,
  703. pkey_ecd_digestverify448
  704. };