eddsa_sig.c 14 KB

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