sm2_sign.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /*
  2. * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright 2017 Ribose Inc. All Rights Reserved.
  4. * Ported from Ribose contributions from Botan.
  5. *
  6. * Licensed under the Apache License 2.0 (the "License"). You may not use
  7. * this file except in compliance with the License. You can obtain a copy
  8. * in the file LICENSE in the source distribution or at
  9. * https://www.openssl.org/source/license.html
  10. */
  11. #include "internal/deprecated.h"
  12. #include "crypto/sm2.h"
  13. #include "crypto/sm2err.h"
  14. #include "crypto/ec.h" /* ossl_ec_group_do_inverse_ord() */
  15. #include "internal/numbers.h"
  16. #include <openssl/err.h>
  17. #include <openssl/evp.h>
  18. #include <openssl/err.h>
  19. #include <openssl/bn.h>
  20. #include <string.h>
  21. int ossl_sm2_compute_z_digest(uint8_t *out,
  22. const EVP_MD *digest,
  23. const uint8_t *id,
  24. const size_t id_len,
  25. const EC_KEY *key)
  26. {
  27. int rc = 0;
  28. const EC_GROUP *group = EC_KEY_get0_group(key);
  29. BN_CTX *ctx = NULL;
  30. EVP_MD_CTX *hash = NULL;
  31. BIGNUM *p = NULL;
  32. BIGNUM *a = NULL;
  33. BIGNUM *b = NULL;
  34. BIGNUM *xG = NULL;
  35. BIGNUM *yG = NULL;
  36. BIGNUM *xA = NULL;
  37. BIGNUM *yA = NULL;
  38. int p_bytes = 0;
  39. uint8_t *buf = NULL;
  40. uint16_t entl = 0;
  41. uint8_t e_byte = 0;
  42. hash = EVP_MD_CTX_new();
  43. ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key));
  44. if (hash == NULL || ctx == NULL) {
  45. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  46. goto done;
  47. }
  48. p = BN_CTX_get(ctx);
  49. a = BN_CTX_get(ctx);
  50. b = BN_CTX_get(ctx);
  51. xG = BN_CTX_get(ctx);
  52. yG = BN_CTX_get(ctx);
  53. xA = BN_CTX_get(ctx);
  54. yA = BN_CTX_get(ctx);
  55. if (yA == NULL) {
  56. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  57. goto done;
  58. }
  59. if (!EVP_DigestInit(hash, digest)) {
  60. ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB);
  61. goto done;
  62. }
  63. /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */
  64. if (id_len >= (UINT16_MAX / 8)) {
  65. /* too large */
  66. ERR_raise(ERR_LIB_SM2, SM2_R_ID_TOO_LARGE);
  67. goto done;
  68. }
  69. entl = (uint16_t)(8 * id_len);
  70. e_byte = entl >> 8;
  71. if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
  72. ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB);
  73. goto done;
  74. }
  75. e_byte = entl & 0xFF;
  76. if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
  77. ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB);
  78. goto done;
  79. }
  80. if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) {
  81. ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB);
  82. goto done;
  83. }
  84. if (!EC_GROUP_get_curve(group, p, a, b, ctx)) {
  85. ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB);
  86. goto done;
  87. }
  88. p_bytes = BN_num_bytes(p);
  89. buf = OPENSSL_zalloc(p_bytes);
  90. if (buf == NULL) {
  91. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  92. goto done;
  93. }
  94. if (BN_bn2binpad(a, buf, p_bytes) < 0
  95. || !EVP_DigestUpdate(hash, buf, p_bytes)
  96. || BN_bn2binpad(b, buf, p_bytes) < 0
  97. || !EVP_DigestUpdate(hash, buf, p_bytes)
  98. || !EC_POINT_get_affine_coordinates(group,
  99. EC_GROUP_get0_generator(group),
  100. xG, yG, ctx)
  101. || BN_bn2binpad(xG, buf, p_bytes) < 0
  102. || !EVP_DigestUpdate(hash, buf, p_bytes)
  103. || BN_bn2binpad(yG, buf, p_bytes) < 0
  104. || !EVP_DigestUpdate(hash, buf, p_bytes)
  105. || !EC_POINT_get_affine_coordinates(group,
  106. EC_KEY_get0_public_key(key),
  107. xA, yA, ctx)
  108. || BN_bn2binpad(xA, buf, p_bytes) < 0
  109. || !EVP_DigestUpdate(hash, buf, p_bytes)
  110. || BN_bn2binpad(yA, buf, p_bytes) < 0
  111. || !EVP_DigestUpdate(hash, buf, p_bytes)
  112. || !EVP_DigestFinal(hash, out, NULL)) {
  113. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  114. goto done;
  115. }
  116. rc = 1;
  117. done:
  118. OPENSSL_free(buf);
  119. BN_CTX_free(ctx);
  120. EVP_MD_CTX_free(hash);
  121. return rc;
  122. }
  123. static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
  124. const EC_KEY *key,
  125. const uint8_t *id,
  126. const size_t id_len,
  127. const uint8_t *msg, size_t msg_len)
  128. {
  129. EVP_MD_CTX *hash = EVP_MD_CTX_new();
  130. const int md_size = EVP_MD_size(digest);
  131. uint8_t *z = NULL;
  132. BIGNUM *e = NULL;
  133. EVP_MD *fetched_digest = NULL;
  134. OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key);
  135. const char *propq = ossl_ec_key_get0_propq(key);
  136. if (md_size < 0) {
  137. ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_DIGEST);
  138. goto done;
  139. }
  140. z = OPENSSL_zalloc(md_size);
  141. if (hash == NULL || z == NULL) {
  142. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  143. goto done;
  144. }
  145. fetched_digest = EVP_MD_fetch(libctx, EVP_MD_name(digest), propq);
  146. if (fetched_digest == NULL) {
  147. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  148. goto done;
  149. }
  150. if (!ossl_sm2_compute_z_digest(z, fetched_digest, id, id_len, key)) {
  151. /* SM2err already called */
  152. goto done;
  153. }
  154. if (!EVP_DigestInit(hash, fetched_digest)
  155. || !EVP_DigestUpdate(hash, z, md_size)
  156. || !EVP_DigestUpdate(hash, msg, msg_len)
  157. /* reuse z buffer to hold H(Z || M) */
  158. || !EVP_DigestFinal(hash, z, NULL)) {
  159. ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB);
  160. goto done;
  161. }
  162. e = BN_bin2bn(z, md_size, NULL);
  163. if (e == NULL)
  164. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  165. done:
  166. EVP_MD_free(fetched_digest);
  167. OPENSSL_free(z);
  168. EVP_MD_CTX_free(hash);
  169. return e;
  170. }
  171. static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
  172. {
  173. const BIGNUM *dA = EC_KEY_get0_private_key(key);
  174. const EC_GROUP *group = EC_KEY_get0_group(key);
  175. const BIGNUM *order = EC_GROUP_get0_order(group);
  176. ECDSA_SIG *sig = NULL;
  177. EC_POINT *kG = NULL;
  178. BN_CTX *ctx = NULL;
  179. BIGNUM *k = NULL;
  180. BIGNUM *rk = NULL;
  181. BIGNUM *r = NULL;
  182. BIGNUM *s = NULL;
  183. BIGNUM *x1 = NULL;
  184. BIGNUM *tmp = NULL;
  185. OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key);
  186. kG = EC_POINT_new(group);
  187. ctx = BN_CTX_new_ex(libctx);
  188. if (kG == NULL || ctx == NULL) {
  189. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  190. goto done;
  191. }
  192. BN_CTX_start(ctx);
  193. k = BN_CTX_get(ctx);
  194. rk = BN_CTX_get(ctx);
  195. x1 = BN_CTX_get(ctx);
  196. tmp = BN_CTX_get(ctx);
  197. if (tmp == NULL) {
  198. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  199. goto done;
  200. }
  201. /*
  202. * These values are returned and so should not be allocated out of the
  203. * context
  204. */
  205. r = BN_new();
  206. s = BN_new();
  207. if (r == NULL || s == NULL) {
  208. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  209. goto done;
  210. }
  211. for (;;) {
  212. if (!BN_priv_rand_range_ex(k, order, ctx)) {
  213. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  214. goto done;
  215. }
  216. if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
  217. || !EC_POINT_get_affine_coordinates(group, kG, x1, NULL,
  218. ctx)
  219. || !BN_mod_add(r, e, x1, order, ctx)) {
  220. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  221. goto done;
  222. }
  223. /* try again if r == 0 or r+k == n */
  224. if (BN_is_zero(r))
  225. continue;
  226. if (!BN_add(rk, r, k)) {
  227. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  228. goto done;
  229. }
  230. if (BN_cmp(rk, order) == 0)
  231. continue;
  232. if (!BN_add(s, dA, BN_value_one())
  233. || !ossl_ec_group_do_inverse_ord(group, s, s, ctx)
  234. || !BN_mod_mul(tmp, dA, r, order, ctx)
  235. || !BN_sub(tmp, k, tmp)
  236. || !BN_mod_mul(s, s, tmp, order, ctx)) {
  237. ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
  238. goto done;
  239. }
  240. sig = ECDSA_SIG_new();
  241. if (sig == NULL) {
  242. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  243. goto done;
  244. }
  245. /* takes ownership of r and s */
  246. ECDSA_SIG_set0(sig, r, s);
  247. break;
  248. }
  249. done:
  250. if (sig == NULL) {
  251. BN_free(r);
  252. BN_free(s);
  253. }
  254. BN_CTX_free(ctx);
  255. EC_POINT_free(kG);
  256. return sig;
  257. }
  258. static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig,
  259. const BIGNUM *e)
  260. {
  261. int ret = 0;
  262. const EC_GROUP *group = EC_KEY_get0_group(key);
  263. const BIGNUM *order = EC_GROUP_get0_order(group);
  264. BN_CTX *ctx = NULL;
  265. EC_POINT *pt = NULL;
  266. BIGNUM *t = NULL;
  267. BIGNUM *x1 = NULL;
  268. const BIGNUM *r = NULL;
  269. const BIGNUM *s = NULL;
  270. OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key);
  271. ctx = BN_CTX_new_ex(libctx);
  272. pt = EC_POINT_new(group);
  273. if (ctx == NULL || pt == NULL) {
  274. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  275. goto done;
  276. }
  277. BN_CTX_start(ctx);
  278. t = BN_CTX_get(ctx);
  279. x1 = BN_CTX_get(ctx);
  280. if (x1 == NULL) {
  281. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  282. goto done;
  283. }
  284. /*
  285. * B1: verify whether r' in [1,n-1], verification failed if not
  286. * B2: verify whether s' in [1,n-1], verification failed if not
  287. * B3: set M'~=ZA || M'
  288. * B4: calculate e'=Hv(M'~)
  289. * B5: calculate t = (r' + s') modn, verification failed if t=0
  290. * B6: calculate the point (x1', y1')=[s']G + [t]PA
  291. * B7: calculate R=(e'+x1') modn, verification pass if yes, otherwise failed
  292. */
  293. ECDSA_SIG_get0(sig, &r, &s);
  294. if (BN_cmp(r, BN_value_one()) < 0
  295. || BN_cmp(s, BN_value_one()) < 0
  296. || BN_cmp(order, r) <= 0
  297. || BN_cmp(order, s) <= 0) {
  298. ERR_raise(ERR_LIB_SM2, SM2_R_BAD_SIGNATURE);
  299. goto done;
  300. }
  301. if (!BN_mod_add(t, r, s, order, ctx)) {
  302. ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
  303. goto done;
  304. }
  305. if (BN_is_zero(t)) {
  306. ERR_raise(ERR_LIB_SM2, SM2_R_BAD_SIGNATURE);
  307. goto done;
  308. }
  309. if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx)
  310. || !EC_POINT_get_affine_coordinates(group, pt, x1, NULL, ctx)) {
  311. ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB);
  312. goto done;
  313. }
  314. if (!BN_mod_add(t, e, x1, order, ctx)) {
  315. ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
  316. goto done;
  317. }
  318. if (BN_cmp(r, t) == 0)
  319. ret = 1;
  320. done:
  321. EC_POINT_free(pt);
  322. BN_CTX_free(ctx);
  323. return ret;
  324. }
  325. ECDSA_SIG *ossl_sm2_do_sign(const EC_KEY *key,
  326. const EVP_MD *digest,
  327. const uint8_t *id,
  328. const size_t id_len,
  329. const uint8_t *msg, size_t msg_len)
  330. {
  331. BIGNUM *e = NULL;
  332. ECDSA_SIG *sig = NULL;
  333. e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
  334. if (e == NULL) {
  335. /* SM2err already called */
  336. goto done;
  337. }
  338. sig = sm2_sig_gen(key, e);
  339. done:
  340. BN_free(e);
  341. return sig;
  342. }
  343. int ossl_sm2_do_verify(const EC_KEY *key,
  344. const EVP_MD *digest,
  345. const ECDSA_SIG *sig,
  346. const uint8_t *id,
  347. const size_t id_len,
  348. const uint8_t *msg, size_t msg_len)
  349. {
  350. BIGNUM *e = NULL;
  351. int ret = 0;
  352. e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
  353. if (e == NULL) {
  354. /* SM2err already called */
  355. goto done;
  356. }
  357. ret = sm2_sig_verify(key, sig, e);
  358. done:
  359. BN_free(e);
  360. return ret;
  361. }
  362. int ossl_sm2_internal_sign(const unsigned char *dgst, int dgstlen,
  363. unsigned char *sig, unsigned int *siglen,
  364. EC_KEY *eckey)
  365. {
  366. BIGNUM *e = NULL;
  367. ECDSA_SIG *s = NULL;
  368. int sigleni;
  369. int ret = -1;
  370. e = BN_bin2bn(dgst, dgstlen, NULL);
  371. if (e == NULL) {
  372. ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
  373. goto done;
  374. }
  375. s = sm2_sig_gen(eckey, e);
  376. if (s == NULL) {
  377. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  378. goto done;
  379. }
  380. sigleni = i2d_ECDSA_SIG(s, &sig);
  381. if (sigleni < 0) {
  382. ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
  383. goto done;
  384. }
  385. *siglen = (unsigned int)sigleni;
  386. ret = 1;
  387. done:
  388. ECDSA_SIG_free(s);
  389. BN_free(e);
  390. return ret;
  391. }
  392. int ossl_sm2_internal_verify(const unsigned char *dgst, int dgstlen,
  393. const unsigned char *sig, int sig_len,
  394. EC_KEY *eckey)
  395. {
  396. ECDSA_SIG *s = NULL;
  397. BIGNUM *e = NULL;
  398. const unsigned char *p = sig;
  399. unsigned char *der = NULL;
  400. int derlen = -1;
  401. int ret = -1;
  402. s = ECDSA_SIG_new();
  403. if (s == NULL) {
  404. ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE);
  405. goto done;
  406. }
  407. if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) {
  408. ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING);
  409. goto done;
  410. }
  411. /* Ensure signature uses DER and doesn't have trailing garbage */
  412. derlen = i2d_ECDSA_SIG(s, &der);
  413. if (derlen != sig_len || memcmp(sig, der, derlen) != 0) {
  414. ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING);
  415. goto done;
  416. }
  417. e = BN_bin2bn(dgst, dgstlen, NULL);
  418. if (e == NULL) {
  419. ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
  420. goto done;
  421. }
  422. ret = sm2_sig_verify(eckey, s, e);
  423. done:
  424. OPENSSL_free(der);
  425. BN_free(e);
  426. ECDSA_SIG_free(s);
  427. return ret;
  428. }