eddsa.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. * Copyright 2020-2021 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. #include <openssl/crypto.h>
  10. #include <openssl/core_dispatch.h>
  11. #include <openssl/core_names.h>
  12. #include <openssl/err.h>
  13. #include <openssl/params.h>
  14. #include <openssl/evp.h>
  15. #include <openssl/err.h>
  16. #include <openssl/proverr.h>
  17. #include "internal/nelem.h"
  18. #include "internal/sizes.h"
  19. #include "prov/providercommon.h"
  20. #include "prov/implementations.h"
  21. #include "prov/provider_ctx.h"
  22. #include "prov/der_ecx.h"
  23. #include "crypto/ecx.h"
  24. #ifdef S390X_EC_ASM
  25. # include "s390x_arch.h"
  26. # define S390X_CAN_SIGN(edtype) \
  27. ((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \
  28. && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \
  29. && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype)))
  30. static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
  31. const unsigned char *tbs, size_t tbslen);
  32. static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
  33. const unsigned char *tbs, size_t tbslen);
  34. static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
  35. const unsigned char *sig,
  36. const unsigned char *tbs, size_t tbslen);
  37. static int s390x_ed448_digestverify(const ECX_KEY *edkey,
  38. const unsigned char *sig,
  39. const unsigned char *tbs, size_t tbslen);
  40. #endif /* S390X_EC_ASM */
  41. static OSSL_FUNC_signature_newctx_fn eddsa_newctx;
  42. static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init;
  43. static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign;
  44. static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign;
  45. static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify;
  46. static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify;
  47. static OSSL_FUNC_signature_freectx_fn eddsa_freectx;
  48. static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx;
  49. static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params;
  50. static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params;
  51. typedef struct {
  52. OSSL_LIB_CTX *libctx;
  53. ECX_KEY *key;
  54. /* The Algorithm Identifier of the signature algorithm */
  55. unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
  56. unsigned char *aid;
  57. size_t aid_len;
  58. } PROV_EDDSA_CTX;
  59. static void *eddsa_newctx(void *provctx, const char *propq_unused)
  60. {
  61. PROV_EDDSA_CTX *peddsactx;
  62. if (!ossl_prov_is_running())
  63. return NULL;
  64. peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX));
  65. if (peddsactx == NULL) {
  66. ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
  67. return NULL;
  68. }
  69. peddsactx->libctx = PROV_LIBCTX_OF(provctx);
  70. return peddsactx;
  71. }
  72. static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname,
  73. void *vedkey,
  74. ossl_unused const OSSL_PARAM params[])
  75. {
  76. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  77. ECX_KEY *edkey = (ECX_KEY *)vedkey;
  78. WPACKET pkt;
  79. int ret;
  80. if (!ossl_prov_is_running())
  81. return 0;
  82. if (mdname != NULL && mdname[0] != '\0') {
  83. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
  84. return 0;
  85. }
  86. if (!ossl_ecx_key_up_ref(edkey)) {
  87. ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
  88. return 0;
  89. }
  90. /*
  91. * We do not care about DER writing errors.
  92. * All it really means is that for some reason, there's no
  93. * AlgorithmIdentifier to be had, but the operation itself is
  94. * still valid, just as long as it's not used to construct
  95. * anything that needs an AlgorithmIdentifier.
  96. */
  97. peddsactx->aid_len = 0;
  98. ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
  99. switch (edkey->type) {
  100. case ECX_KEY_TYPE_ED25519:
  101. ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
  102. break;
  103. case ECX_KEY_TYPE_ED448:
  104. ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
  105. break;
  106. default:
  107. /* Should never happen */
  108. ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
  109. return 0;
  110. }
  111. if (ret && WPACKET_finish(&pkt)) {
  112. WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
  113. peddsactx->aid = WPACKET_get_curr(&pkt);
  114. }
  115. WPACKET_cleanup(&pkt);
  116. peddsactx->key = edkey;
  117. return 1;
  118. }
  119. int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret,
  120. size_t *siglen, size_t sigsize,
  121. const unsigned char *tbs, size_t tbslen)
  122. {
  123. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  124. const ECX_KEY *edkey = peddsactx->key;
  125. if (!ossl_prov_is_running())
  126. return 0;
  127. if (sigret == NULL) {
  128. *siglen = ED25519_SIGSIZE;
  129. return 1;
  130. }
  131. if (sigsize < ED25519_SIGSIZE) {
  132. ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
  133. return 0;
  134. }
  135. #ifdef S390X_EC_ASM
  136. if (S390X_CAN_SIGN(ED25519))
  137. return s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen);
  138. #endif /* S390X_EC_ASM */
  139. if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
  140. peddsactx->libctx, NULL) == 0) {
  141. ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
  142. return 0;
  143. }
  144. *siglen = ED25519_SIGSIZE;
  145. return 1;
  146. }
  147. int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret,
  148. size_t *siglen, size_t sigsize,
  149. const unsigned char *tbs, size_t tbslen)
  150. {
  151. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  152. const ECX_KEY *edkey = peddsactx->key;
  153. if (!ossl_prov_is_running())
  154. return 0;
  155. if (sigret == NULL) {
  156. *siglen = ED448_SIGSIZE;
  157. return 1;
  158. }
  159. if (sigsize < ED448_SIGSIZE) {
  160. ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
  161. return 0;
  162. }
  163. #ifdef S390X_EC_ASM
  164. if (S390X_CAN_SIGN(ED448))
  165. return s390x_ed448_digestsign(edkey, sigret, tbs, tbslen);
  166. #endif /* S390X_EC_ASM */
  167. if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey,
  168. edkey->privkey, NULL, 0, edkey->propq) == 0) {
  169. ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
  170. return 0;
  171. }
  172. *siglen = ED448_SIGSIZE;
  173. return 1;
  174. }
  175. int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig,
  176. size_t siglen, const unsigned char *tbs,
  177. size_t tbslen)
  178. {
  179. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  180. const ECX_KEY *edkey = peddsactx->key;
  181. if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
  182. return 0;
  183. #ifdef S390X_EC_ASM
  184. if (S390X_CAN_SIGN(ED25519))
  185. return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
  186. #endif /* S390X_EC_ASM */
  187. return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
  188. peddsactx->libctx, edkey->propq);
  189. }
  190. int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig,
  191. size_t siglen, const unsigned char *tbs,
  192. size_t tbslen)
  193. {
  194. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  195. const ECX_KEY *edkey = peddsactx->key;
  196. if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
  197. return 0;
  198. #ifdef S390X_EC_ASM
  199. if (S390X_CAN_SIGN(ED448))
  200. return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
  201. #endif /* S390X_EC_ASM */
  202. return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
  203. NULL, 0, edkey->propq);
  204. }
  205. static void eddsa_freectx(void *vpeddsactx)
  206. {
  207. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  208. ossl_ecx_key_free(peddsactx->key);
  209. OPENSSL_free(peddsactx);
  210. }
  211. static void *eddsa_dupctx(void *vpeddsactx)
  212. {
  213. PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
  214. PROV_EDDSA_CTX *dstctx;
  215. if (!ossl_prov_is_running())
  216. return NULL;
  217. dstctx = OPENSSL_zalloc(sizeof(*srcctx));
  218. if (dstctx == NULL)
  219. return NULL;
  220. *dstctx = *srcctx;
  221. dstctx->key = NULL;
  222. if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
  223. ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
  224. goto err;
  225. }
  226. dstctx->key = srcctx->key;
  227. return dstctx;
  228. err:
  229. eddsa_freectx(dstctx);
  230. return NULL;
  231. }
  232. static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
  233. {
  234. PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
  235. OSSL_PARAM *p;
  236. if (peddsactx == NULL)
  237. return 0;
  238. p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
  239. if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid,
  240. peddsactx->aid_len))
  241. return 0;
  242. return 1;
  243. }
  244. static const OSSL_PARAM known_gettable_ctx_params[] = {
  245. OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
  246. OSSL_PARAM_END
  247. };
  248. static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
  249. ossl_unused void *provctx)
  250. {
  251. return known_gettable_ctx_params;
  252. }
  253. const OSSL_DISPATCH ossl_ed25519_signature_functions[] = {
  254. { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
  255. { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
  256. (void (*)(void))eddsa_digest_signverify_init },
  257. { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
  258. (void (*)(void))ed25519_digest_sign },
  259. { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
  260. (void (*)(void))eddsa_digest_signverify_init },
  261. { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
  262. (void (*)(void))ed25519_digest_verify },
  263. { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
  264. { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
  265. { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
  266. { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
  267. (void (*)(void))eddsa_gettable_ctx_params },
  268. { 0, NULL }
  269. };
  270. const OSSL_DISPATCH ossl_ed448_signature_functions[] = {
  271. { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
  272. { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
  273. (void (*)(void))eddsa_digest_signverify_init },
  274. { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
  275. (void (*)(void))ed448_digest_sign },
  276. { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
  277. (void (*)(void))eddsa_digest_signverify_init },
  278. { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
  279. (void (*)(void))ed448_digest_verify },
  280. { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
  281. { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
  282. { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
  283. { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
  284. (void (*)(void))eddsa_gettable_ctx_params },
  285. { 0, NULL }
  286. };
  287. #ifdef S390X_EC_ASM
  288. static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
  289. const unsigned char *tbs, size_t tbslen)
  290. {
  291. int rc;
  292. union {
  293. struct {
  294. unsigned char sig[64];
  295. unsigned char priv[32];
  296. } ed25519;
  297. unsigned long long buff[512];
  298. } param;
  299. memset(&param, 0, sizeof(param));
  300. memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
  301. rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
  302. OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
  303. if (rc != 0)
  304. return 0;
  305. s390x_flip_endian32(sig, param.ed25519.sig);
  306. s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
  307. return 1;
  308. }
  309. static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
  310. const unsigned char *tbs, size_t tbslen)
  311. {
  312. int rc;
  313. union {
  314. struct {
  315. unsigned char sig[128];
  316. unsigned char priv[64];
  317. } ed448;
  318. unsigned long long buff[512];
  319. } param;
  320. memset(&param, 0, sizeof(param));
  321. memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
  322. rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
  323. OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
  324. if (rc != 0)
  325. return 0;
  326. s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
  327. s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
  328. memcpy(sig, param.ed448.sig, 57);
  329. memcpy(sig + 57, param.ed448.sig + 64, 57);
  330. return 1;
  331. }
  332. static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
  333. const unsigned char *sig,
  334. const unsigned char *tbs, size_t tbslen)
  335. {
  336. union {
  337. struct {
  338. unsigned char sig[64];
  339. unsigned char pub[32];
  340. } ed25519;
  341. unsigned long long buff[512];
  342. } param;
  343. memset(&param, 0, sizeof(param));
  344. s390x_flip_endian32(param.ed25519.sig, sig);
  345. s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
  346. s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
  347. return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
  348. &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
  349. }
  350. static int s390x_ed448_digestverify(const ECX_KEY *edkey,
  351. const unsigned char *sig,
  352. const unsigned char *tbs,
  353. size_t tbslen)
  354. {
  355. union {
  356. struct {
  357. unsigned char sig[128];
  358. unsigned char pub[64];
  359. } ed448;
  360. unsigned long long buff[512];
  361. } param;
  362. memset(&param, 0, sizeof(param));
  363. memcpy(param.ed448.sig, sig, 57);
  364. s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
  365. memcpy(param.ed448.sig + 64, sig + 57, 57);
  366. s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
  367. memcpy(param.ed448.pub, edkey->pubkey, 57);
  368. s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
  369. return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
  370. &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
  371. }
  372. #endif /* S390X_EC_ASM */