summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/sm2/sm2.h147
-rw-r--r--src/lib/libcrypto/sm2/sm2_crypt.c632
-rw-r--r--src/lib/libcrypto/sm2/sm2_err.c106
-rw-r--r--src/lib/libcrypto/sm2/sm2_locl.h43
-rw-r--r--src/lib/libcrypto/sm2/sm2_pmeth.c316
-rw-r--r--src/lib/libcrypto/sm2/sm2_sign.c465
-rw-r--r--src/lib/libcrypto/sm2/sm2_za.c161
7 files changed, 1870 insertions, 0 deletions
diff --git a/src/lib/libcrypto/sm2/sm2.h b/src/lib/libcrypto/sm2/sm2.h
new file mode 100644
index 0000000000..92eef8a6de
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2.h
@@ -0,0 +1,147 @@
1/* $OpenBSD: sm2.h,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Copyright (c) 2017, 2019 Ribose Inc
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef HEADER_SM2_H
19#define HEADER_SM2_H
20
21#include <openssl/opensslconf.h>
22
23#include <openssl/ec.h>
24#include <openssl/ecdsa.h>
25
26#ifdef OPENSSL_NO_SM2
27#error SM2 is disabled.
28#endif
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34/*
35 * SM2 signature generation.
36 */
37int SM2_sign(const unsigned char *dgst, int dgstlen, unsigned char *sig,
38 unsigned int *siglen, EC_KEY *eckey);
39
40/*
41 * SM2 signature verification. Assumes input is an SM3 digest
42 */
43int SM2_verify(const unsigned char *dgst, int dgstlen, const unsigned char *sig,
44 int siglen, EC_KEY *eckey);
45
46/*
47 * SM2 encryption
48 */
49int SM2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
50 size_t *c_size);
51
52int SM2_plaintext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
53 size_t *pl_size);
54
55int SM2_encrypt(const EC_KEY *key, const EVP_MD *digest, const uint8_t *msg,
56 size_t msg_len, uint8_t *ciphertext_buf, size_t *ciphertext_len);
57
58int SM2_decrypt(const EC_KEY *key, const EVP_MD *digest,
59 const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *ptext_buf,
60 size_t *ptext_len);
61
62/* BEGIN ERROR CODES */
63/* The following lines are auto generated by the script mkerr.pl. Any changes
64 * made after this point may be overwritten when the script is next run.
65 */
66void ERR_load_SM2_strings(void);
67
68/* Error codes for the SM2 functions. */
69
70/* Function codes. */
71# define SM2_F_PKEY_SM2_CTRL 274
72# define SM2_F_PKEY_SM2_CTRL_STR 275
73# define SM2_F_PKEY_SM2_KEYGEN 276
74# define SM2_F_PKEY_SM2_PARAMGEN 277
75# define SM2_F_PKEY_SM2_SIGN 278
76# define SM2_F_PKEY_SM2_VERIFY 279
77# define SM2_F_PKEY_SM2_ENCRYPT 280
78# define SM2_F_PKEY_SM2_DECRYPT 281
79
80/* Reason codes. */
81# define SM2_R_ASN1_ERROR 115
82# define SM2_R_ASN5_ERROR 1150
83# define SM2_R_BAD_SIGNATURE 156
84# define SM2_R_BIGNUM_OUT_OF_RANGE 144
85# define SM2_R_BUFFER_TOO_SMALL 100
86# define SM2_R_COORDINATES_OUT_OF_RANGE 146
87# define SM2_R_CURVE_DOES_NOT_SUPPORT_ECDH 160
88# define SM2_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159
89# define SM2_R_D2I_ECPKPARAMETERS_FAILURE 117
90# define SM2_R_DECODE_ERROR 142
91# define SM2_R_DIGEST_FAILURE 163
92# define SM2_R_DISCRIMINANT_IS_ZERO 118
93# define SM2_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
94# define SM2_R_FIELD_TOO_LARGE 143
95# define SM2_R_GF2M_NOT_SUPPORTED 147
96# define SM2_R_GROUP2PKPARAMETERS_FAILURE 120
97# define SM2_R_I2D_ECPKPARAMETERS_FAILURE 121
98# define SM2_R_INCOMPATIBLE_OBJECTS 101
99# define SM2_R_INVALID_ARGUMENT 112
100# define SM2_R_INVALID_COMPRESSED_POINT 110
101# define SM2_R_INVALID_COMPRESSION_BIT 109
102# define SM2_R_INVALID_CURVE 141
103# define SM2_R_INVALID_DIGEST 151
104# define SM2_R_INVALID_DIGEST_TYPE 138
105# define SM2_R_INVALID_ENCODING 102
106# define SM2_R_INVALID_FIELD 103
107# define SM2_R_INVALID_FORM 104
108# define SM2_R_INVALID_GROUP_ORDER 122
109# define SM2_R_INVALID_KEY 116
110# define SM2_R_INVALID_OUTPUT_LENGTH 161
111# define SM2_R_INVALID_PEER_KEY 133
112# define SM2_R_INVALID_PENTANOMIAL_BASIS 132
113# define SM2_R_INVALID_PRIVATE_KEY 123
114# define SM2_R_INVALID_TRINOMIAL_BASIS 137
115# define SM2_R_KDF_FAILURE 162
116# define SM2_R_KDF_PARAMETER_ERROR 148
117# define SM2_R_KEYS_NOT_SET 140
118# define SM2_R_MISSING_PARAMETERS 124
119# define SM2_R_MISSING_PRIVATE_KEY 125
120# define SM2_R_NEED_NEW_SETUP_VALUES 157
121# define SM2_R_NOT_A_NIST_PRIME 135
122# define SM2_R_NOT_IMPLEMENTED 126
123# define SM2_R_NOT_INITIALIZED 111
124# define SM2_R_NO_PARAMETERS_SET 139
125# define SM2_R_NO_PRIVATE_VALUE 154
126# define SM2_R_OPERATION_NOT_SUPPORTED 152
127# define SM2_R_PASSED_NULL_PARAMETER 134
128# define SM2_R_PEER_KEY_ERROR 149
129# define SM2_R_PKPARAMETERS2GROUP_FAILURE 127
130# define SM2_R_POINT_ARITHMETIC_FAILURE 155
131# define SM2_R_POINT_AT_INFINITY 106
132# define SM2_R_POINT_IS_NOT_ON_CURVE 107
133# define SM2_R_RANDOM_NUMBER_GENERATION_FAILED 158
134# define SM2_R_SHARED_INFO_ERROR 150
135# define SM2_R_SLOT_FULL 108
136# define SM2_R_UNDEFINED_GENERATOR 113
137# define SM2_R_UNDEFINED_ORDER 128
138# define SM2_R_UNKNOWN_GROUP 129
139# define SM2_R_UNKNOWN_ORDER 114
140# define SM2_R_UNSUPPORTED_FIELD 131
141# define SM2_R_WRONG_CURVE_PARAMETERS 145
142# define SM2_R_WRONG_ORDER 130
143
144#ifdef __cplusplus
145}
146#endif
147#endif
diff --git a/src/lib/libcrypto/sm2/sm2_crypt.c b/src/lib/libcrypto/sm2/sm2_crypt.c
new file mode 100644
index 0000000000..2bb3b8ff63
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2_crypt.c
@@ -0,0 +1,632 @@
1/* $OpenBSD: sm2_crypt.c,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Copyright (c) 2017, 2019 Ribose Inc
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef OPENSSL_NO_SM2
19
20#include <string.h>
21
22#include <openssl/asn1.h>
23#include <openssl/asn1t.h>
24#include <openssl/bn.h>
25#include <openssl/err.h>
26#include <openssl/evp.h>
27#include <openssl/sm2.h>
28
29#include "sm2_locl.h"
30
31typedef struct SM2_Ciphertext_st SM2_Ciphertext;
32
33SM2_Ciphertext *SM2_Ciphertext_new(void);
34void SM2_Ciphertext_free(SM2_Ciphertext *a);
35SM2_Ciphertext *d2i_SM2_Ciphertext(SM2_Ciphertext **a, const unsigned char **in,
36 long len);
37int i2d_SM2_Ciphertext(SM2_Ciphertext *a, unsigned char **out);
38
39struct SM2_Ciphertext_st {
40 BIGNUM *C1x;
41 BIGNUM *C1y;
42 ASN1_OCTET_STRING *C3;
43 ASN1_OCTET_STRING *C2;
44};
45
46static const ASN1_TEMPLATE SM2_Ciphertext_seq_tt[] = {
47 {
48 .flags = 0,
49 .tag = 0,
50 .offset = offsetof(SM2_Ciphertext, C1x),
51 .field_name = "C1x",
52 .item = &BIGNUM_it,
53 },
54 {
55 .flags = 0,
56 .tag = 0,
57 .offset = offsetof(SM2_Ciphertext, C1y),
58 .field_name = "C1y",
59 .item = &BIGNUM_it,
60 },
61 {
62 .flags = 0,
63 .tag = 0,
64 .offset = offsetof(SM2_Ciphertext, C3),
65 .field_name = "C3",
66 .item = &ASN1_OCTET_STRING_it,
67 },
68 {
69 .flags = 0,
70 .tag = 0,
71 .offset = offsetof(SM2_Ciphertext, C2),
72 .field_name = "C2",
73 .item = &ASN1_OCTET_STRING_it,
74 },
75};
76
77const ASN1_ITEM SM2_Ciphertext_it = {
78 .itype = ASN1_ITYPE_SEQUENCE,
79 .utype = V_ASN1_SEQUENCE,
80 .templates = SM2_Ciphertext_seq_tt,
81 .tcount = sizeof(SM2_Ciphertext_seq_tt) / sizeof(ASN1_TEMPLATE),
82 .funcs = NULL,
83 .size = sizeof(SM2_Ciphertext),
84 .sname = "SM2_Ciphertext",
85};
86
87SM2_Ciphertext *
88d2i_SM2_Ciphertext(SM2_Ciphertext **a, const unsigned char **in, long len)
89{
90 return (SM2_Ciphertext *) ASN1_item_d2i((ASN1_VALUE **)a, in, len,
91 &SM2_Ciphertext_it);
92}
93
94int
95i2d_SM2_Ciphertext(SM2_Ciphertext *a, unsigned char **out)
96{
97 return ASN1_item_i2d((ASN1_VALUE *)a, out, &SM2_Ciphertext_it);
98}
99
100SM2_Ciphertext *
101SM2_Ciphertext_new(void)
102{
103 return (SM2_Ciphertext *)ASN1_item_new(&SM2_Ciphertext_it);
104}
105
106void
107SM2_Ciphertext_free(SM2_Ciphertext *a)
108{
109 ASN1_item_free((ASN1_VALUE *)a, &SM2_Ciphertext_it);
110}
111
112static size_t
113ec_field_size(const EC_GROUP *group)
114{
115 /* Is there some simpler way to do this? */
116 BIGNUM *p;
117 size_t field_size = 0;
118
119 if ((p = BN_new()) == NULL)
120 goto err;
121 if (!EC_GROUP_get_curve(group, p, NULL, NULL, NULL))
122 goto err;
123 field_size = BN_num_bytes(p);
124 err:
125 BN_free(p);
126 return field_size;
127}
128
129int
130SM2_plaintext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
131 size_t *pl_size)
132{
133 size_t field_size, overhead;
134 int md_size;
135
136 if ((field_size = ec_field_size(EC_KEY_get0_group(key))) == 0) {
137 SM2error(SM2_R_INVALID_FIELD);
138 return 0;
139 }
140
141 if ((md_size = EVP_MD_size(digest)) < 0) {
142 SM2error(SM2_R_INVALID_DIGEST);
143 return 0;
144 }
145
146 overhead = 10 + 2 * field_size + md_size;
147 if (msg_len <= overhead) {
148 SM2error(SM2_R_INVALID_ARGUMENT);
149 return 0;
150 }
151
152 *pl_size = msg_len - overhead;
153 return 1;
154}
155
156int
157SM2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
158 size_t *c_size)
159{
160 size_t asn_size, field_size;
161 int md_size;
162
163 if ((field_size = ec_field_size(EC_KEY_get0_group(key))) == 0) {
164 SM2error(SM2_R_INVALID_FIELD);
165 return 0;
166 }
167
168 if ((md_size = EVP_MD_size(digest)) < 0) {
169 SM2error(SM2_R_INVALID_DIGEST);
170 return 0;
171 }
172
173 asn_size = 2 * ASN1_object_size(0, field_size + 1, V_ASN1_INTEGER) +
174 ASN1_object_size(0, md_size, V_ASN1_OCTET_STRING) +
175 ASN1_object_size(0, msg_len, V_ASN1_OCTET_STRING);
176
177 *c_size = ASN1_object_size(1, asn_size, V_ASN1_SEQUENCE);
178 return 1;
179}
180
181int
182sm2_kdf(uint8_t *key, size_t key_len, uint8_t *secret, size_t secret_len,
183 const EVP_MD *digest)
184{
185 EVP_MD_CTX *hash;
186 uint8_t *hash_buf = NULL;
187 uint32_t ctr = 1;
188 uint8_t ctr_buf[4] = {0};
189 size_t hadd, hlen;
190 int rc = 0;
191
192 if ((hash = EVP_MD_CTX_new()) == NULL) {
193 SM2error(ERR_R_MALLOC_FAILURE);
194 goto err;
195 }
196
197 if ((hlen = EVP_MD_size(digest)) < 0) {
198 SM2error(SM2_R_INVALID_DIGEST);
199 goto err;
200 }
201 if ((hash_buf = malloc(hlen)) == NULL) {
202 SM2error(ERR_R_MALLOC_FAILURE);
203 goto err;
204 }
205
206 EVP_MD_CTX_init(hash);
207 while ((key_len > 0) && (ctr != 0)) {
208 if (!EVP_DigestInit_ex(hash, digest, NULL)) {
209 SM2error(ERR_R_EVP_LIB);
210 goto err;
211 }
212 if (!EVP_DigestUpdate(hash, secret, secret_len)) {
213 SM2error(ERR_R_EVP_LIB);
214 goto err;
215 }
216
217 /* big-endian counter representation */
218 ctr_buf[0] = (ctr >> 24) & 0xff;
219 ctr_buf[1] = (ctr >> 16) & 0xff;
220 ctr_buf[2] = (ctr >> 8) & 0xff;
221 ctr_buf[3] = ctr & 0xff;
222 ctr++;
223
224 if (!EVP_DigestUpdate(hash, ctr_buf, 4)) {
225 SM2error(ERR_R_EVP_LIB);
226 goto err;
227 }
228 if (!EVP_DigestFinal(hash, hash_buf, NULL)) {
229 SM2error(ERR_R_EVP_LIB);
230 goto err;
231 }
232
233 hadd = key_len > hlen ? hlen : key_len;
234 memcpy(key, hash_buf, hadd);
235 memset(hash_buf, 0, hlen);
236 key_len -= hadd;
237 key += hadd;
238 }
239
240 rc = 1;
241 err:
242 free(hash_buf);
243 EVP_MD_CTX_free(hash);
244 return rc;
245}
246
247int
248SM2_encrypt(const EC_KEY *key, const EVP_MD *digest, const uint8_t *msg,
249 size_t msg_len, uint8_t *ciphertext_buf, size_t *ciphertext_len)
250{
251 SM2_Ciphertext ctext_struct;
252 EVP_MD_CTX *hash = NULL;
253 BN_CTX *ctx = NULL;
254 BIGNUM *order = NULL;
255 BIGNUM *k, *x1, *y1, *x2, *y2;
256 const EC_GROUP *group;
257 const EC_POINT *P;
258 EC_POINT *kG = NULL, *kP = NULL;
259 uint8_t *msg_mask = NULL, *x2y2 = NULL, *C3 = NULL;
260 size_t C3_size, field_size, i, x2size, y2size;
261 int rc = 0;
262 int clen;
263
264 ctext_struct.C2 = NULL;
265 ctext_struct.C3 = NULL;
266
267 if ((hash = EVP_MD_CTX_new()) == NULL) {
268 SM2error(ERR_R_MALLOC_FAILURE);
269 goto err;
270 }
271
272 if ((group = EC_KEY_get0_group(key)) == NULL) {
273 SM2error(SM2_R_INVALID_KEY);
274 goto err;
275 }
276
277 if ((order = BN_new()) == NULL) {
278 SM2error(ERR_R_MALLOC_FAILURE);
279 goto err;
280 }
281
282 if (!EC_GROUP_get_order(group, order, NULL)) {
283 SM2error(SM2_R_INVALID_GROUP_ORDER);
284 goto err;
285 }
286
287 if ((P = EC_KEY_get0_public_key(key)) == NULL) {
288 SM2error(SM2_R_INVALID_KEY);
289 goto err;
290 }
291
292 if ((field_size = ec_field_size(group)) == 0) {
293 SM2error(SM2_R_INVALID_FIELD);
294 goto err;
295 }
296
297 if ((C3_size = EVP_MD_size(digest)) < 0) {
298 SM2error(SM2_R_INVALID_DIGEST);
299 goto err;
300 }
301
302 if ((kG = EC_POINT_new(group)) == NULL) {
303 SM2error(ERR_R_MALLOC_FAILURE);
304 goto err;
305 }
306 if ((kP = EC_POINT_new(group)) == NULL) {
307 SM2error(ERR_R_MALLOC_FAILURE);
308 goto err;
309 }
310
311 if ((ctx = BN_CTX_new()) == NULL) {
312 SM2error(ERR_R_MALLOC_FAILURE);
313 goto err;
314 }
315
316 BN_CTX_start(ctx);
317 if ((k = BN_CTX_get(ctx)) == NULL) {
318 SM2error(ERR_R_BN_LIB);
319 goto err;
320 }
321 if ((x1 = BN_CTX_get(ctx)) == NULL) {
322 SM2error(ERR_R_BN_LIB);
323 goto err;
324 }
325 if ((x2 = BN_CTX_get(ctx)) == NULL) {
326 SM2error(ERR_R_BN_LIB);
327 goto err;
328 }
329 if ((y1 = BN_CTX_get(ctx)) == NULL) {
330 SM2error(ERR_R_BN_LIB);
331 goto err;
332 }
333 if ((y2 = BN_CTX_get(ctx)) == NULL) {
334 SM2error(ERR_R_BN_LIB);
335 goto err;
336 }
337
338 if ((x2y2 = calloc(2, field_size)) == NULL) {
339 SM2error(ERR_R_MALLOC_FAILURE);
340 goto err;
341 }
342
343 if ((C3 = calloc(1, C3_size)) == NULL) {
344 SM2error(ERR_R_MALLOC_FAILURE);
345 goto err;
346 }
347
348 memset(ciphertext_buf, 0, *ciphertext_len);
349
350 if (!BN_rand_range(k, order)) {
351 SM2error(SM2_R_RANDOM_NUMBER_GENERATION_FAILED);
352 goto err;
353 }
354
355 if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)) {
356 SM2error(ERR_R_EC_LIB);
357 goto err;
358 }
359
360 if (!EC_POINT_get_affine_coordinates(group, kG, x1, y1, ctx)) {
361 SM2error(ERR_R_EC_LIB);
362 goto err;
363 }
364
365 if (!EC_POINT_mul(group, kP, NULL, P, k, ctx)) {
366 SM2error(ERR_R_EC_LIB);
367 goto err;
368 }
369
370 if (!EC_POINT_get_affine_coordinates(group, kP, x2, y2, ctx)) {
371 SM2error(ERR_R_EC_LIB);
372 goto err;
373 }
374
375 if ((x2size = BN_num_bytes(x2)) > field_size ||
376 (y2size = BN_num_bytes(y2)) > field_size) {
377 SM2error(SM2_R_BIGNUM_OUT_OF_RANGE);
378 goto err;
379 }
380
381 BN_bn2bin(x2, x2y2 + field_size - x2size);
382 BN_bn2bin(y2, x2y2 + 2 * field_size - y2size);
383
384 if ((msg_mask = calloc(1, msg_len)) == NULL) {
385 SM2error(ERR_R_MALLOC_FAILURE);
386 goto err;
387 }
388
389 if (!sm2_kdf(msg_mask, msg_len, x2y2, 2 * field_size, digest)) {
390 SM2error(SM2_R_KDF_FAILURE);
391 goto err;
392 }
393
394 for (i = 0; i != msg_len; i++)
395 msg_mask[i] ^= msg[i];
396
397 if (!EVP_DigestInit(hash, digest)) {
398 SM2error(ERR_R_EVP_LIB);
399 goto err;
400 }
401
402 if (!EVP_DigestUpdate(hash, x2y2, field_size)) {
403 SM2error(ERR_R_EVP_LIB);
404 goto err;
405 }
406
407 if (!EVP_DigestUpdate(hash, msg, msg_len)) {
408 SM2error(ERR_R_EVP_LIB);
409 goto err;
410 }
411
412 if (!EVP_DigestUpdate(hash, x2y2 + field_size, field_size)) {
413 SM2error(ERR_R_EVP_LIB);
414 goto err;
415 }
416
417 if (!EVP_DigestFinal(hash, C3, NULL)) {
418 SM2error(ERR_R_EVP_LIB);
419 goto err;
420 }
421
422 ctext_struct.C1x = x1;
423 ctext_struct.C1y = y1;
424 if ((ctext_struct.C3 = ASN1_OCTET_STRING_new()) == NULL) {
425 SM2error(ERR_R_MALLOC_FAILURE);
426 goto err;
427 }
428 if ((ctext_struct.C2 = ASN1_OCTET_STRING_new()) == NULL) {
429 SM2error(ERR_R_MALLOC_FAILURE);
430 goto err;
431 }
432 if (!ASN1_OCTET_STRING_set(ctext_struct.C3, C3, C3_size)) {
433 SM2error(ERR_R_INTERNAL_ERROR);
434 goto err;
435 }
436 if (!ASN1_OCTET_STRING_set(ctext_struct.C2, msg_mask, msg_len)) {
437 SM2error(ERR_R_INTERNAL_ERROR);
438 goto err;
439 }
440
441 if ((clen = i2d_SM2_Ciphertext(&ctext_struct, &ciphertext_buf)) < 0) {
442 SM2error(ERR_R_INTERNAL_ERROR);
443 goto err;
444 }
445
446 *ciphertext_len = clen;
447 rc = 1;
448
449 err:
450 ASN1_OCTET_STRING_free(ctext_struct.C2);
451 ASN1_OCTET_STRING_free(ctext_struct.C3);
452 free(msg_mask);
453 free(x2y2);
454 free(C3);
455 EVP_MD_CTX_free(hash);
456 BN_CTX_end(ctx);
457 BN_CTX_free(ctx);
458 EC_POINT_free(kG);
459 EC_POINT_free(kP);
460 BN_free(order);
461 return rc;
462}
463
464int
465SM2_decrypt(const EC_KEY *key, const EVP_MD *digest, const uint8_t *ciphertext,
466 size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len)
467{
468 SM2_Ciphertext *sm2_ctext = NULL;
469 EVP_MD_CTX *hash = NULL;
470 BN_CTX *ctx = NULL;
471 BIGNUM *x2, *y2;
472 const EC_GROUP *group;
473 EC_POINT *C1 = NULL;
474 const uint8_t *C2, *C3;
475 uint8_t *computed_C3 = NULL, *msg_mask = NULL, *x2y2 = NULL;
476 size_t field_size, x2size, y2size;
477 int msg_len = 0, rc = 0;
478 int hash_size, i;
479
480 if ((group = EC_KEY_get0_group(key)) == NULL) {
481 SM2error(SM2_R_INVALID_KEY);
482 goto err;
483 }
484
485 if ((field_size = ec_field_size(group)) == 0) {
486 SM2error(SM2_R_INVALID_FIELD);
487 goto err;
488 }
489
490 if ((hash_size = EVP_MD_size(digest)) < 0) {
491 SM2error(SM2_R_INVALID_DIGEST);
492 goto err;
493 }
494
495 memset(ptext_buf, 0xFF, *ptext_len);
496
497 if ((sm2_ctext = d2i_SM2_Ciphertext(NULL, &ciphertext,
498 ciphertext_len)) == NULL) {
499 SM2error(SM2_R_ASN1_ERROR);
500 goto err;
501 }
502
503 if (sm2_ctext->C3->length != hash_size) {
504 SM2error(SM2_R_INVALID_ENCODING);
505 goto err;
506 }
507
508 C2 = sm2_ctext->C2->data;
509 C3 = sm2_ctext->C3->data;
510 msg_len = sm2_ctext->C2->length;
511
512 if ((ctx = BN_CTX_new()) == NULL) {
513 SM2error(ERR_R_MALLOC_FAILURE);
514 goto err;
515 }
516
517 BN_CTX_start(ctx);
518 if ((x2 = BN_CTX_get(ctx)) == NULL) {
519 SM2error(ERR_R_BN_LIB);
520 goto err;
521 }
522 if ((y2 = BN_CTX_get(ctx)) == NULL) {
523 SM2error(ERR_R_BN_LIB);
524 goto err;
525 }
526
527 if ((msg_mask = calloc(1, msg_len)) == NULL) {
528 SM2error(ERR_R_MALLOC_FAILURE);
529 goto err;
530 }
531 if ((x2y2 = calloc(2, field_size)) == NULL) {
532 SM2error(ERR_R_MALLOC_FAILURE);
533 goto err;
534 }
535 if ((computed_C3 = calloc(1, hash_size)) == NULL) {
536 SM2error(ERR_R_MALLOC_FAILURE);
537 goto err;
538 }
539
540 if ((C1 = EC_POINT_new(group)) == NULL) {
541 SM2error(ERR_R_MALLOC_FAILURE);
542 goto err;
543 }
544
545 if (!EC_POINT_set_affine_coordinates(group, C1, sm2_ctext->C1x,
546 sm2_ctext->C1y, ctx))
547 {
548 SM2error(ERR_R_EC_LIB);
549 goto err;
550 }
551
552 if (!EC_POINT_mul(group, C1, NULL, C1, EC_KEY_get0_private_key(key),
553 ctx)) {
554 SM2error(ERR_R_EC_LIB);
555 goto err;
556 }
557
558 if (!EC_POINT_get_affine_coordinates(group, C1, x2, y2, ctx)) {
559 SM2error(ERR_R_EC_LIB);
560 goto err;
561 }
562
563 if ((x2size = BN_num_bytes(x2)) > field_size ||
564 (y2size = BN_num_bytes(y2)) > field_size) {
565 SM2error(SM2_R_BIGNUM_OUT_OF_RANGE);
566 goto err;
567 }
568
569 BN_bn2bin(x2, x2y2 + field_size - x2size);
570 BN_bn2bin(y2, x2y2 + 2 * field_size - y2size);
571
572 if (!sm2_kdf(msg_mask, msg_len, x2y2, 2 * field_size, digest)) {
573 SM2error(SM2_R_KDF_FAILURE);
574 goto err;
575 }
576
577 for (i = 0; i != msg_len; ++i)
578 ptext_buf[i] = C2[i] ^ msg_mask[i];
579
580 if ((hash = EVP_MD_CTX_new()) == NULL) {
581 SM2error(ERR_R_EVP_LIB);
582 goto err;
583 }
584
585 if (!EVP_DigestInit(hash, digest)) {
586 SM2error(ERR_R_EVP_LIB);
587 goto err;
588 }
589
590 if (!EVP_DigestUpdate(hash, x2y2, field_size)) {
591 SM2error(ERR_R_EVP_LIB);
592 goto err;
593 }
594
595 if (!EVP_DigestUpdate(hash, ptext_buf, msg_len)) {
596 SM2error(ERR_R_EVP_LIB);
597 goto err;
598 }
599
600 if (!EVP_DigestUpdate(hash, x2y2 + field_size, field_size)) {
601 SM2error(ERR_R_EVP_LIB);
602 goto err;
603 }
604
605 if (!EVP_DigestFinal(hash, computed_C3, NULL)) {
606 SM2error(ERR_R_EVP_LIB);
607 goto err;
608 }
609
610 if (memcmp(computed_C3, C3, hash_size) != 0)
611 goto err;
612
613 rc = 1;
614 *ptext_len = msg_len;
615
616 err:
617 if (rc == 0)
618 memset(ptext_buf, 0, *ptext_len);
619
620 free(msg_mask);
621 free(x2y2);
622 free(computed_C3);
623 EC_POINT_free(C1);
624 BN_CTX_end(ctx);
625 BN_CTX_free(ctx);
626 SM2_Ciphertext_free(sm2_ctext);
627 EVP_MD_CTX_free(hash);
628
629 return rc;
630}
631
632#endif /* OPENSSL_NO_SM2 */
diff --git a/src/lib/libcrypto/sm2/sm2_err.c b/src/lib/libcrypto/sm2/sm2_err.c
new file mode 100644
index 0000000000..d34123cbf9
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2_err.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: sm2_err.c,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Generated by util/mkerr.pl DO NOT EDIT
4 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
5 *
6 * Licensed under the OpenSSL license (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
12#ifndef OPENSSL_NO_SM2
13
14#include <openssl/err.h>
15#include <openssl/sm2.h>
16
17#ifndef OPENSSL_NO_ERR
18
19#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SM2,func,0)
20#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SM2,0,reason)
21
22static ERR_STRING_DATA SM2_str_functs[] = {
23 {ERR_FUNC(0xfff), "CRYPTO_internal"},
24 {0, NULL}
25};
26
27static ERR_STRING_DATA SM2_str_reasons[] = {
28 {ERR_REASON(SM2_R_ASN1_ERROR), "asn1 error"},
29 {ERR_REASON(SM2_R_ASN5_ERROR), "asn5 error"},
30 {ERR_REASON(SM2_R_BAD_SIGNATURE), "bad signature"},
31 {ERR_REASON(SM2_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
32 {ERR_REASON(SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
33 {ERR_REASON(SM2_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
34 {ERR_REASON(SM2_R_CURVE_DOES_NOT_SUPPORT_ECDH), "curve does not support ecdh"},
35 {ERR_REASON(SM2_R_CURVE_DOES_NOT_SUPPORT_SIGNING), "curve does not support signing"},
36 {ERR_REASON(SM2_R_D2I_ECPKPARAMETERS_FAILURE), "d2i ecpkparameters failure"},
37 {ERR_REASON(SM2_R_DECODE_ERROR), "decode error"},
38 {ERR_REASON(SM2_R_DIGEST_FAILURE), "digest calculation failure"},
39 {ERR_REASON(SM2_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
40 {ERR_REASON(SM2_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"},
41 {ERR_REASON(SM2_R_FIELD_TOO_LARGE), "field too large"},
42 {ERR_REASON(SM2_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
43 {ERR_REASON(SM2_R_GROUP2PKPARAMETERS_FAILURE), "group2pkparameters failure"},
44 {ERR_REASON(SM2_R_I2D_ECPKPARAMETERS_FAILURE), "i2d ecpkparameters failure"},
45 {ERR_REASON(SM2_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
46 {ERR_REASON(SM2_R_INVALID_ARGUMENT), "invalid argument"},
47 {ERR_REASON(SM2_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
48 {ERR_REASON(SM2_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
49 {ERR_REASON(SM2_R_INVALID_CURVE), "invalid curve"},
50 {ERR_REASON(SM2_R_INVALID_DIGEST), "invalid digest"},
51 {ERR_REASON(SM2_R_INVALID_DIGEST_TYPE), "invalid digest type"},
52 {ERR_REASON(SM2_R_INVALID_ENCODING), "invalid encoding"},
53 {ERR_REASON(SM2_R_INVALID_FIELD), "invalid field"},
54 {ERR_REASON(SM2_R_INVALID_FORM), "invalid form"},
55 {ERR_REASON(SM2_R_INVALID_GROUP_ORDER), "invalid group order"},
56 {ERR_REASON(SM2_R_INVALID_KEY), "invalid key"},
57 {ERR_REASON(SM2_R_INVALID_OUTPUT_LENGTH), "invalid output length"},
58 {ERR_REASON(SM2_R_INVALID_PEER_KEY), "invalid peer key"},
59 {ERR_REASON(SM2_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
60 {ERR_REASON(SM2_R_INVALID_PRIVATE_KEY), "invalid private key"},
61 {ERR_REASON(SM2_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
62 {ERR_REASON(SM2_R_KDF_FAILURE), "kdf calculation failure"},
63 {ERR_REASON(SM2_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
64 {ERR_REASON(SM2_R_KEYS_NOT_SET), "keys not set"},
65 {ERR_REASON(SM2_R_MISSING_PARAMETERS), "missing parameters"},
66 {ERR_REASON(SM2_R_MISSING_PRIVATE_KEY), "missing private key"},
67 {ERR_REASON(SM2_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
68 {ERR_REASON(SM2_R_NOT_A_NIST_PRIME), "not a NIST prime"},
69 {ERR_REASON(SM2_R_NOT_IMPLEMENTED), "not implemented"},
70 {ERR_REASON(SM2_R_NOT_INITIALIZED), "not initialized"},
71 {ERR_REASON(SM2_R_NO_PARAMETERS_SET), "no parameters set"},
72 {ERR_REASON(SM2_R_NO_PRIVATE_VALUE), "no private value"},
73 {ERR_REASON(SM2_R_OPERATION_NOT_SUPPORTED), "operation not supported"},
74 {ERR_REASON(SM2_R_PASSED_NULL_PARAMETER), "passed null parameter"},
75 {ERR_REASON(SM2_R_PEER_KEY_ERROR), "peer key error"},
76 {ERR_REASON(SM2_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"},
77 {ERR_REASON(SM2_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
78 {ERR_REASON(SM2_R_POINT_AT_INFINITY), "point at infinity"},
79 {ERR_REASON(SM2_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
80 {ERR_REASON(SM2_R_RANDOM_NUMBER_GENERATION_FAILED), "random number generation failed"},
81 {ERR_REASON(SM2_R_SHARED_INFO_ERROR), "shared info error"},
82 {ERR_REASON(SM2_R_SLOT_FULL), "slot full"},
83 {ERR_REASON(SM2_R_UNDEFINED_GENERATOR), "undefined generator"},
84 {ERR_REASON(SM2_R_UNDEFINED_ORDER), "undefined order"},
85 {ERR_REASON(SM2_R_UNKNOWN_GROUP), "unknown group"},
86 {ERR_REASON(SM2_R_UNKNOWN_ORDER), "unknown order"},
87 {ERR_REASON(SM2_R_UNSUPPORTED_FIELD), "unsupported field"},
88 {ERR_REASON(SM2_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
89 {ERR_REASON(SM2_R_WRONG_ORDER), "wrong order"},
90 {0, NULL}
91};
92
93#endif
94
95void
96ERR_load_SM2_strings(void)
97{
98#ifndef OPENSSL_NO_ERR
99 if (ERR_func_error_string(SM2_str_functs[0].error) == NULL) {
100 ERR_load_strings(0, SM2_str_functs);
101 ERR_load_strings(0, SM2_str_reasons);
102 }
103#endif
104}
105
106#endif /* OPENSSL_NO_SM2 */
diff --git a/src/lib/libcrypto/sm2/sm2_locl.h b/src/lib/libcrypto/sm2/sm2_locl.h
new file mode 100644
index 0000000000..2e1626824f
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2_locl.h
@@ -0,0 +1,43 @@
1/* $OpenBSD: sm2_locl.h,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Copyright (c) 2017, 2019 Ribose Inc
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef HEADER_SM2_LOCL_H
19#define HEADER_SM2_LOCL_H
20
21#include <openssl/ec.h>
22#include <openssl/ecdsa.h>
23
24__BEGIN_HIDDEN_DECLS
25
26int sm2_compute_userid_digest(uint8_t *out, const EVP_MD *digest,
27 const uint8_t *uid, size_t uid_len, const EC_KEY *key);
28
29/*
30 * SM2 signature operation. Computes ZA (user id digest) and then signs
31 * H(ZA || msg) using SM2
32 */
33ECDSA_SIG *sm2_do_sign(const EC_KEY *key, const EVP_MD *digest,
34 const uint8_t *uid, size_t uid_len, const uint8_t *msg, size_t msg_len);
35
36int sm2_do_verify(const EC_KEY *key, const EVP_MD *digest,
37 const ECDSA_SIG *signature, const uint8_t *uid, size_t uid_len,
38 const uint8_t *msg, size_t msg_len);
39
40__END_HIDDEN_DECLS
41
42#endif
43
diff --git a/src/lib/libcrypto/sm2/sm2_pmeth.c b/src/lib/libcrypto/sm2/sm2_pmeth.c
new file mode 100644
index 0000000000..af6e180a70
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2_pmeth.c
@@ -0,0 +1,316 @@
1/* $OpenBSD: sm2_pmeth.c,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Copyright (c) 2017, 2019 Ribose Inc
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef OPENSSL_NO_SM2
19
20#include <string.h>
21
22#include <openssl/sm2.h>
23#include <openssl/asn1t.h>
24#include <openssl/x509.h>
25#include <openssl/err.h>
26#include <openssl/evp.h>
27
28#include "evp_locl.h"
29#include "sm2_locl.h"
30
31/* SM2 pkey context structure */
32
33typedef struct {
34 /* key and paramgen group */
35 EC_GROUP *gen_group;
36 /* message digest */
37 const EVP_MD *md;
38 EVP_MD_CTX *md_ctx;
39 /* personalization string */
40 uint8_t* uid;
41 size_t uid_len;
42} SM2_PKEY_CTX;
43
44static int
45pkey_sm2_init(EVP_PKEY_CTX *ctx)
46{
47 SM2_PKEY_CTX *dctx;
48
49 if ((dctx = calloc(1, sizeof(*dctx))) == NULL) {
50 SM2error(ERR_R_MALLOC_FAILURE);
51 return 0;
52 }
53 ctx->data = dctx;
54 return 1;
55}
56
57static void
58pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
59{
60 SM2_PKEY_CTX *dctx = ctx->data;
61
62 if (ctx == NULL || ctx->data == NULL)
63 return;
64
65 EC_GROUP_free(dctx->gen_group);
66 free(dctx->uid);
67 free(dctx);
68 ctx->data = NULL;
69}
70
71static int
72pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
73{
74 SM2_PKEY_CTX *dctx, *sctx;
75
76 if (!pkey_sm2_init(dst))
77 return 0;
78 sctx = src->data;
79 dctx = dst->data;
80 if (sctx->gen_group) {
81 if ((dctx->gen_group = EC_GROUP_dup(sctx->gen_group)) == NULL) {
82 SM2error(ERR_R_MALLOC_FAILURE);
83 goto err;
84 }
85 }
86
87 if (sctx->uid != NULL) {
88 if ((dctx->uid = malloc(sctx->uid_len)) == NULL) {
89 SM2error(ERR_R_MALLOC_FAILURE);
90 goto err;
91 }
92 memcpy(dctx->uid, sctx->uid, sctx->uid_len);
93 dctx->uid_len = sctx->uid_len;
94 }
95
96 dctx->md = sctx->md;
97
98 if (!EVP_MD_CTX_copy(dctx->md_ctx, sctx->md_ctx))
99 goto err;
100
101 return 1;
102
103 err:
104 pkey_sm2_cleanup(dst);
105 return 0;
106}
107
108static int
109pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
110 const unsigned char *tbs, size_t tbslen)
111{
112 unsigned int sltmp;
113 int ret, sig_sz;
114
115 if ((sig_sz = ECDSA_size(ctx->pkey->pkey.ec)) <= 0)
116 return 0;
117
118 if (sig == NULL) {
119 *siglen = sig_sz;
120 return 1;
121 }
122
123 if (*siglen < (size_t)sig_sz) {
124 SM2error(SM2_R_BUFFER_TOO_SMALL);
125 return 0;
126 }
127
128 if ((ret = SM2_sign(tbs, tbslen, sig, &sltmp, ctx->pkey->pkey.ec)) <= 0)
129 return ret;
130
131 *siglen = (size_t)sltmp;
132 return 1;
133}
134
135static int
136pkey_sm2_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
137 const unsigned char *tbs, size_t tbslen)
138{
139 return SM2_verify(tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec);
140}
141
142static int
143pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
144 const unsigned char *in, size_t inlen)
145{
146 SM2_PKEY_CTX *dctx = ctx->data;
147 const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md;
148
149 if (out == NULL) {
150 if (!SM2_ciphertext_size(ctx->pkey->pkey.ec, md, inlen, outlen))
151 return -1;
152 else
153 return 1;
154 }
155
156 return SM2_encrypt(ctx->pkey->pkey.ec, md, in, inlen, out, outlen);
157}
158
159static int
160pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
161 const unsigned char *in, size_t inlen)
162{
163 SM2_PKEY_CTX *dctx = ctx->data;
164 const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md;
165
166 if (out == NULL) {
167 if (!SM2_plaintext_size(ctx->pkey->pkey.ec, md, inlen, outlen))
168 return -1;
169 else
170 return 1;
171 }
172
173 return SM2_decrypt(ctx->pkey->pkey.ec, md, in, inlen, out, outlen);
174}
175
176static int
177pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
178{
179 SM2_PKEY_CTX *dctx = ctx->data;
180 EC_GROUP *group = NULL;
181
182 switch (type) {
183 case EVP_PKEY_CTRL_DIGESTINIT:
184 dctx->md_ctx = p2;
185 return 1;
186
187 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
188 if ((group = EC_GROUP_new_by_curve_name(p1)) == NULL) {
189 SM2error(SM2_R_INVALID_CURVE);
190 return 0;
191 }
192 EC_GROUP_free(dctx->gen_group);
193 dctx->gen_group = group;
194 return 1;
195
196 case EVP_PKEY_CTRL_SM2_SET_UID:
197 if ((p1 < 0) || ((p1 == 0) && (p2 != NULL))) {
198 SM2error(SM2_R_INVALID_ARGUMENT);
199 return 0;
200 }
201 if ((p1 > 0) && (p2 == NULL)) {
202 SM2error(ERR_R_PASSED_NULL_PARAMETER);
203 return 0;
204 }
205 free(dctx->uid);
206 if (p2 == NULL) {
207 dctx->uid = NULL;
208 dctx->uid_len = 0;
209 return 1;
210 }
211
212 if ((dctx->uid = malloc(p1)) == NULL) {
213 SM2error(ERR_R_MALLOC_FAILURE);
214 return 1;
215 }
216 memcpy(dctx->uid, p2, p1);
217 dctx->uid_len = p1;
218 return 1;
219
220 case EVP_PKEY_CTRL_SM2_HASH_UID:
221 {
222 const EVP_MD* md;
223 uint8_t za[EVP_MAX_MD_SIZE] = {0};
224 int md_len;
225
226 if (dctx->uid == NULL) {
227 SM2error(SM2_R_INVALID_ARGUMENT);
228 return 0;
229 }
230
231 if ((md = EVP_MD_CTX_md(dctx->md_ctx)) == NULL) {
232 SM2error(ERR_R_EVP_LIB);
233 return 0;
234 }
235
236 if ((md_len = EVP_MD_size(md)) < 0) {
237 SM2error(SM2_R_INVALID_DIGEST);
238 return 0;
239 }
240
241 if (sm2_compute_userid_digest(za, md, dctx->uid, dctx->uid_len,
242 ctx->pkey->pkey.ec) != 1) {
243 SM2error(SM2_R_DIGEST_FAILURE);
244 return 0;
245 }
246 return EVP_DigestUpdate(dctx->md_ctx, za, md_len);
247 }
248
249 case EVP_PKEY_CTRL_SM2_GET_UID_LEN:
250 if (p2 == NULL) {
251 SM2error(ERR_R_PASSED_NULL_PARAMETER);
252 return 0;
253 }
254 *(size_t *)p2 = dctx->uid_len;
255 return 1;
256
257 case EVP_PKEY_CTRL_SM2_GET_UID:
258 if (p2 == NULL) {
259 SM2error(ERR_R_PASSED_NULL_PARAMETER);
260 return 0;
261 }
262 if (dctx->uid_len == 0) {
263 return 1;
264 }
265 memcpy(p2, dctx->uid, dctx->uid_len);
266 return 1;
267
268 case EVP_PKEY_CTRL_MD:
269 dctx->md = p2;
270 return 1;
271
272 default:
273 return -2;
274 }
275}
276
277static int
278pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
279{
280 int nid;
281
282 if (strcmp(type, "ec_paramgen_curve") == 0) {
283 if (((nid = EC_curve_nist2nid(value)) == NID_undef) &&
284 ((nid = OBJ_sn2nid(value)) == NID_undef) &&
285 ((nid = OBJ_ln2nid(value)) == NID_undef)) {
286 SM2error(SM2_R_INVALID_CURVE);
287 return 0;
288 }
289 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
290 } else if (strcmp(type, "sm2_uid") == 0) {
291 return EVP_PKEY_CTX_set_sm2_uid(ctx, (void*) value,
292 (int)strlen(value));
293 }
294
295 return -2;
296}
297
298const EVP_PKEY_METHOD sm2_pkey_meth = {
299 .pkey_id = EVP_PKEY_SM2,
300 .init = pkey_sm2_init,
301 .copy = pkey_sm2_copy,
302 .cleanup = pkey_sm2_cleanup,
303
304 .sign = pkey_sm2_sign,
305
306 .verify = pkey_sm2_verify,
307
308 .encrypt = pkey_sm2_encrypt,
309
310 .decrypt = pkey_sm2_decrypt,
311
312 .ctrl = pkey_sm2_ctrl,
313 .ctrl_str = pkey_sm2_ctrl_str
314};
315
316#endif /* OPENSSL_NO_SM2 */
diff --git a/src/lib/libcrypto/sm2/sm2_sign.c b/src/lib/libcrypto/sm2/sm2_sign.c
new file mode 100644
index 0000000000..d306658a48
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2_sign.c
@@ -0,0 +1,465 @@
1/* $OpenBSD: sm2_sign.c,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Copyright (c) 2017, 2019 Ribose Inc
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef OPENSSL_NO_SM2
19
20#include <string.h>
21
22#include <openssl/sm2.h>
23#include <openssl/evp.h>
24#include <openssl/err.h>
25#include <openssl/bn.h>
26
27#include "bn_lcl.h"
28#include "sm2_locl.h"
29
30static BIGNUM *
31sm2_compute_msg_hash(const EVP_MD *digest, const EC_KEY *key,
32 const uint8_t *uid, size_t uid_len, const uint8_t *msg, size_t msg_len)
33{
34 EVP_MD_CTX *hash;
35 BIGNUM *e = NULL;
36 int md_size;
37 uint8_t *za = NULL;
38
39 if ((hash = EVP_MD_CTX_new()) == NULL) {
40 SM2error(ERR_R_MALLOC_FAILURE);
41 goto err;
42 }
43
44 if ((md_size = EVP_MD_size(digest)) < 0) {
45 SM2error(SM2_R_INVALID_DIGEST);
46 goto err;
47 }
48
49 if ((za = calloc(1, md_size)) == NULL) {
50 SM2error(ERR_R_MALLOC_FAILURE);
51 goto err;
52 }
53
54 if (!sm2_compute_userid_digest(za, digest, uid, uid_len, key)) {
55 SM2error(SM2_R_DIGEST_FAILURE);
56 goto err;
57 }
58
59 if (!EVP_DigestInit(hash, digest)) {
60 SM2error(ERR_R_EVP_LIB);
61 goto err;
62 }
63
64 if (!EVP_DigestUpdate(hash, za, md_size)) {
65 SM2error(ERR_R_EVP_LIB);
66 goto err;
67 }
68
69 if (!EVP_DigestUpdate(hash, msg, msg_len)) {
70 SM2error(ERR_R_EVP_LIB);
71 goto err;
72 }
73
74 /* reuse za buffer to hold H(ZA || M) */
75 if (!EVP_DigestFinal(hash, za, NULL)) {
76 SM2error(ERR_R_EVP_LIB);
77 goto err;
78 }
79
80 e = BN_bin2bn(za, md_size, NULL);
81
82 err:
83 free(za);
84 EVP_MD_CTX_free(hash);
85 return e;
86}
87
88static ECDSA_SIG *
89sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
90{
91 ECDSA_SIG *sig = NULL;
92 const EC_GROUP *group;
93 EC_POINT *kG = NULL;
94 BN_CTX *ctx = NULL;
95 const BIGNUM *dA;
96 BIGNUM *order = NULL, *r = NULL, *s = NULL;
97 BIGNUM *k, *rk, *tmp, *x1;
98
99 if ((dA = EC_KEY_get0_private_key(key)) == NULL) {
100 SM2error(SM2_R_INVALID_FIELD);
101 goto err;
102 }
103
104 if ((group = EC_KEY_get0_group(key)) == NULL) {
105 SM2error(SM2_R_INVALID_FIELD);
106 goto err;
107 }
108
109 if ((order = BN_new()) == NULL) {
110 SM2error(ERR_R_MALLOC_FAILURE);
111 goto err;
112 }
113
114 if (!EC_GROUP_get_order(group, order, NULL)) {
115 SM2error(ERR_R_EC_LIB);
116 goto err;
117 }
118
119 if ((kG = EC_POINT_new(group)) == NULL) {
120 SM2error(ERR_R_MALLOC_FAILURE);
121 goto err;
122 }
123
124 if ((ctx = BN_CTX_new()) == NULL) {
125 SM2error(ERR_R_MALLOC_FAILURE);
126 goto err;
127 }
128
129 BN_CTX_start(ctx);
130
131 if ((k = BN_CTX_get(ctx)) == NULL) {
132 SM2error(ERR_R_BN_LIB);
133 goto err;
134 }
135 if ((rk = BN_CTX_get(ctx)) == NULL) {
136 SM2error(ERR_R_BN_LIB);
137 goto err;
138 }
139 if ((x1 = BN_CTX_get(ctx)) == NULL) {
140 SM2error(ERR_R_BN_LIB);
141 goto err;
142 }
143 if ((tmp = BN_CTX_get(ctx)) == NULL) {
144 SM2error(ERR_R_BN_LIB);
145 goto err;
146 }
147
148 /* r and s are returned as part of sig, so they can't be part of ctx. */
149 if ((r = BN_new()) == NULL) {
150 SM2error(ERR_R_MALLOC_FAILURE);
151 goto err;
152 }
153 if ((s = BN_new()) == NULL) {
154 SM2error(ERR_R_MALLOC_FAILURE);
155 goto err;
156 }
157
158 for (;;) {
159 if (!BN_rand_range(k, order)) {
160 SM2error(SM2_R_RANDOM_NUMBER_GENERATION_FAILED);
161 goto err;
162 }
163
164 if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)) {
165 SM2error(ERR_R_EC_LIB);
166 goto err;
167 }
168
169 if (!EC_POINT_get_affine_coordinates(group, kG, x1, NULL,
170 ctx)) {
171 SM2error(ERR_R_EC_LIB);
172 goto err;
173 }
174
175 if (!BN_mod_add(r, e, x1, order, ctx)) {
176 SM2error(ERR_R_BN_LIB);
177 goto err;
178 }
179
180 /* try again if r == 0 or r + k == n */
181 if (BN_is_zero(r))
182 continue;
183
184 if (!BN_add(rk, r, k)) {
185 SM2error(ERR_R_BN_LIB);
186 goto err;
187 }
188
189 if (BN_cmp(rk, order) == 0)
190 continue;
191
192 if (!BN_add(s, dA, BN_value_one())) {
193 SM2error(ERR_R_BN_LIB);
194 goto err;
195 }
196
197 if (!BN_mod_inverse_ct(s, s, order, ctx)) {
198 SM2error(ERR_R_BN_LIB);
199 goto err;
200 }
201
202 if (!BN_mod_mul(tmp, dA, r, order, ctx)) {
203 SM2error(ERR_R_BN_LIB);
204 goto err;
205 }
206
207 if (!BN_sub(tmp, k, tmp)) {
208 SM2error(ERR_R_BN_LIB);
209 goto err;
210 }
211
212 if (!BN_mod_mul(s, s, tmp, order, ctx)) {
213 SM2error(ERR_R_BN_LIB);
214 goto err;
215 }
216
217 if ((sig = ECDSA_SIG_new()) == NULL) {
218 SM2error(ERR_R_MALLOC_FAILURE);
219 goto err;
220 }
221
222 /* sig takes ownership of r and s */
223 if (!ECDSA_SIG_set0(sig, r, s)) {
224 SM2error(ERR_R_INTERNAL_ERROR);
225 goto err;
226 }
227 break;
228 }
229
230 err:
231 if (sig == NULL) {
232 BN_free(r);
233 BN_free(s);
234 }
235
236 BN_free(order);
237 BN_CTX_end(ctx);
238 BN_CTX_free(ctx);
239 EC_POINT_free(kG);
240 return sig;
241}
242
243static int
244sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, const BIGNUM *e)
245{
246 const EC_GROUP *group;
247 EC_POINT *pt = NULL;
248 const BIGNUM *r = NULL, *s = NULL;
249 BN_CTX *ctx = NULL;
250 BIGNUM *order, *t, *x1;
251 int ret = 0;
252
253 if ((group = EC_KEY_get0_group(key)) == NULL) {
254 SM2error(SM2_R_INVALID_FIELD);
255 goto err;
256 }
257
258 if ((ctx = BN_CTX_new()) == NULL) {
259 SM2error(ERR_R_MALLOC_FAILURE);
260 goto err;
261 }
262
263 BN_CTX_start(ctx);
264
265 if ((order = BN_CTX_get(ctx)) == NULL) {
266 SM2error(ERR_R_MALLOC_FAILURE);
267 goto err;
268 }
269
270 if (!EC_GROUP_get_order(group, order, NULL)) {
271 SM2error(ERR_R_EC_LIB);
272 goto err;
273 }
274
275 if ((pt = EC_POINT_new(group)) == NULL) {
276 SM2error(ERR_R_MALLOC_FAILURE);
277 goto err;
278 }
279
280 if ((t = BN_CTX_get(ctx)) == NULL) {
281 SM2error(ERR_R_MALLOC_FAILURE);
282 goto err;
283 }
284 if ((x1 = BN_CTX_get(ctx)) == NULL) {
285 SM2error(ERR_R_MALLOC_FAILURE);
286 goto err;
287 }
288
289 /*
290 * Section 5.3.1 in https://tools.ietf.org/html/draft-shen-sm2-ecdsa-00
291 *
292 * B1: verify that r' is in [1, n-1]
293 * B2: verify that s' is in [1, n-1]
294 * B3: set M' ~= ZA || M'
295 * B4: calculate e' = Hv(M'~)
296 * B5: verify that t = r' + s' (mod n) is not zero
297 * B6: calculate the point (x1', y1') = [s']G + [t]PA
298 * B7: verify that r' == e' + x1' (mod n)
299 */
300
301 ECDSA_SIG_get0(sig, &r, &s);
302
303 /* B1: verify that r' is in [1, n-1] */
304 if (BN_cmp(r, BN_value_one()) < 0 || BN_cmp(order, r) <= 0) {
305 SM2error(SM2_R_BAD_SIGNATURE);
306 goto err;
307 }
308
309 /* B2: verify that s' is in [1, n-1] */
310 if (BN_cmp(s, BN_value_one()) < 0 || BN_cmp(order, s) <= 0) {
311 SM2error(SM2_R_BAD_SIGNATURE);
312 goto err;
313 }
314
315 /* B5: verify that t = r + s is not zero */
316 if (!BN_mod_add(t, r, s, order, ctx)) {
317 SM2error(ERR_R_BN_LIB);
318 goto err;
319 }
320 if (BN_is_zero(t)) {
321 SM2error(SM2_R_BAD_SIGNATURE);
322 goto err;
323 }
324
325 /* B6: calculate pt = (x1', y1') = [s']G + [t]PA */
326 if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx)) {
327 SM2error(ERR_R_EC_LIB);
328 goto err;
329 }
330
331 if (!EC_POINT_get_affine_coordinates(group, pt, x1, NULL, ctx)) {
332 SM2error(ERR_R_EC_LIB);
333 goto err;
334 }
335
336 /* B7: verify that r' == e' + x1' (mod n) */
337 if (!BN_mod_add(t, e, x1, order, ctx)) {
338 SM2error(ERR_R_BN_LIB);
339 goto err;
340 }
341 if (BN_cmp(r, t) == 0)
342 ret = 1;
343
344 err:
345 EC_POINT_free(pt);
346 BN_CTX_end(ctx);
347 BN_CTX_free(ctx);
348 return ret;
349}
350
351ECDSA_SIG *
352sm2_do_sign(const EC_KEY *key, const EVP_MD *digest, const uint8_t *uid,
353 size_t uid_len, const uint8_t *msg, size_t msg_len)
354{
355 ECDSA_SIG *sig = NULL;
356 BIGNUM *e;
357
358 e = sm2_compute_msg_hash(digest, key, uid, uid_len, msg, msg_len);
359 if (e == NULL) {
360 SM2error(SM2_R_DIGEST_FAILURE);
361 goto err;
362 }
363
364 sig = sm2_sig_gen(key, e);
365
366 err:
367 BN_free(e);
368 return sig;
369}
370
371int
372sm2_do_verify(const EC_KEY *key, const EVP_MD *digest, const ECDSA_SIG *sig,
373 const uint8_t *uid, size_t uid_len, const uint8_t *msg, size_t msg_len)
374{
375 BIGNUM *e;
376 int ret = -1;
377
378 e = sm2_compute_msg_hash(digest, key, uid, uid_len, msg, msg_len);
379 if (e == NULL) {
380 SM2error(SM2_R_DIGEST_FAILURE);
381 goto err;
382 }
383
384 ret = sm2_sig_verify(key, sig, e);
385
386 err:
387 BN_free(e);
388 return ret;
389}
390
391int
392SM2_sign(const unsigned char *dgst, int dgstlen, unsigned char *sig,
393 unsigned int *siglen, EC_KEY *eckey)
394{
395 BIGNUM *e;
396 ECDSA_SIG *s = NULL;
397 int outlen = 0;
398 int ret = -1;
399
400 if ((e = BN_bin2bn(dgst, dgstlen, NULL)) == NULL) {
401 SM2error(ERR_R_MALLOC_FAILURE);
402 goto err;
403 }
404
405 if ((s = sm2_sig_gen(eckey, e)) == NULL) {
406 goto err;
407 }
408
409 if ((outlen = i2d_ECDSA_SIG(s, &sig)) < 0) {
410 SM2error(SM2_R_ASN1_ERROR);
411 goto err;
412 }
413
414 *siglen = outlen;
415 ret = 1;
416
417 err:
418 ECDSA_SIG_free(s);
419 BN_free(e);
420 return ret;
421}
422
423int
424SM2_verify(const unsigned char *dgst, int dgstlen, const unsigned char *sig,
425 int sig_len, EC_KEY *eckey)
426{
427 ECDSA_SIG *s;
428 BIGNUM *e = NULL;
429 const unsigned char *p = sig;
430 unsigned char *der = NULL;
431 int derlen = -1;
432 int ret = -1;
433
434 if ((s = ECDSA_SIG_new()) == NULL) {
435 SM2error(ERR_R_MALLOC_FAILURE);
436 goto err;
437 }
438
439 if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) {
440 SM2error(SM2_R_INVALID_ENCODING);
441 goto err;
442 }
443
444 /* Ensure signature uses DER and doesn't have trailing garbage */
445 derlen = i2d_ECDSA_SIG(s, &der);
446 if (derlen != sig_len || memcmp(sig, der, derlen) != 0) {
447 SM2error(SM2_R_INVALID_ENCODING);
448 goto err;
449 }
450
451 if ((e = BN_bin2bn(dgst, dgstlen, NULL)) == NULL) {
452 SM2error(ERR_R_BN_LIB);
453 goto err;
454 }
455
456 ret = sm2_sig_verify(eckey, s, e);
457
458 err:
459 free(der);
460 BN_free(e);
461 ECDSA_SIG_free(s);
462 return ret;
463}
464
465#endif /* OPENSSL_NO_SM2 */
diff --git a/src/lib/libcrypto/sm2/sm2_za.c b/src/lib/libcrypto/sm2/sm2_za.c
new file mode 100644
index 0000000000..2a7f2846ec
--- /dev/null
+++ b/src/lib/libcrypto/sm2/sm2_za.c
@@ -0,0 +1,161 @@
1/* $OpenBSD: sm2_za.c,v 1.1.1.1 2021/08/18 16:04:32 tb Exp $ */
2/*
3 * Copyright (c) 2017, 2019 Ribose Inc
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef OPENSSL_NO_SM2
19
20#include <openssl/sm2.h>
21#include <openssl/evp.h>
22#include <openssl/bn.h>
23#include <string.h>
24
25int
26sm2_compute_userid_digest(uint8_t *out, const EVP_MD *digest, uint8_t *uid,
27 size_t uid_len, const EC_KEY *key)
28{
29 const EC_GROUP *group;
30 EVP_MD_CTX *hash = NULL;
31 BN_CTX *ctx = NULL;
32 BIGNUM *p, *a, *b, *xG, *yG, *xA, *yA;
33 uint8_t *buf = NULL;
34 uint16_t entla;
35 uint8_t e_byte;
36 int bytes, p_bytes;
37 int rc = 0;
38
39 if ((group = EC_KEY_get0_group(key)) == NULL)
40 goto err;
41
42 if ((hash = EVP_MD_CTX_new()) == NULL)
43 goto err;
44
45 if ((ctx = BN_CTX_new()) == NULL)
46 goto err;
47
48 if ((p = BN_CTX_get(ctx)) == NULL)
49 goto err;
50 if ((a = BN_CTX_get(ctx)) == NULL)
51 goto err;
52 if ((b = BN_CTX_get(ctx)) == NULL)
53 goto err;
54 if ((xG = BN_CTX_get(ctx)) == NULL)
55 goto err;
56 if ((yG = BN_CTX_get(ctx)) == NULL)
57 goto err;
58 if ((xA = BN_CTX_get(ctx)) == NULL)
59 goto err;
60 if ((yA = BN_CTX_get(ctx)) == NULL)
61 goto err;
62
63 memset(out, 0, EVP_MD_size(digest));
64
65 if (!EVP_DigestInit(hash, digest))
66 goto err;
67
68 /*
69 * ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
70 */
71
72 if (uid_len >= 8192)
73 goto err;
74
75 entla = (unsigned short)(8 * uid_len);
76
77 e_byte = entla >> 8;
78 if (!EVP_DigestUpdate(hash, &e_byte, 1))
79 goto err;
80
81 e_byte = entla & 0xFF;
82 if (!EVP_DigestUpdate(hash, &e_byte, 1))
83 goto err;
84
85 if (!EVP_DigestUpdate(hash, uid, uid_len))
86 goto err;
87
88 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
89 goto err;
90
91 p_bytes = BN_num_bytes(p);
92
93 if ((buf = calloc(1, p_bytes)) == NULL)
94 goto err;
95
96 if ((bytes = BN_num_bytes(a)) > p_bytes)
97 goto err;
98 BN_bn2bin(a, buf + p_bytes - bytes);
99 if (!EVP_DigestUpdate(hash, buf, p_bytes))
100 goto err;
101
102 if ((bytes = BN_num_bytes(b)) > p_bytes)
103 goto err;
104 memset(buf, 0, p_bytes - bytes);
105 BN_bn2bin(b, buf + p_bytes - bytes);
106 if (!EVP_DigestUpdate(hash, buf, p_bytes))
107 goto err;
108
109 if (!EC_POINT_get_affine_coordinates(group,
110 EC_GROUP_get0_generator(group), xG, yG, ctx))
111 goto err;
112
113 if ((bytes = BN_num_bytes(xG)) > p_bytes)
114 goto err;
115 memset(buf, 0, p_bytes - bytes);
116 BN_bn2bin(xG, buf + p_bytes - bytes);
117
118 if (!EVP_DigestUpdate(hash, buf, p_bytes))
119 goto err;
120
121 if ((bytes = BN_num_bytes(yG)) > p_bytes)
122 goto err;
123 memset(buf, 0, p_bytes - bytes);
124 BN_bn2bin(yG, buf + p_bytes - bytes);
125
126 if (!EVP_DigestUpdate(hash, buf, p_bytes))
127 goto err;
128
129 if (!EC_POINT_get_affine_coordinates(group,
130 EC_KEY_get0_public_key(key), xA, yA, ctx))
131 goto err;
132
133 if ((bytes = BN_num_bytes(xA)) > p_bytes)
134 goto err;
135 memset(buf, 0, p_bytes - bytes);
136 BN_bn2bin(xA, buf + p_bytes - bytes);
137
138 if (!EVP_DigestUpdate(hash, buf, p_bytes))
139 goto err;
140
141 if ((bytes = BN_num_bytes(yA)) > p_bytes)
142 goto err;
143 memset(buf, 0, p_bytes - bytes);
144 BN_bn2bin(yA, buf + p_bytes - bytes);
145
146 if (!EVP_DigestUpdate(hash, buf, p_bytes))
147 goto err;
148
149 if (!EVP_DigestFinal(hash, out, NULL))
150 goto err;
151
152 rc = 1;
153
154 err:
155 free(buf);
156 BN_CTX_free(ctx);
157 EVP_MD_CTX_free(hash);
158 return rc;
159}
160
161#endif /* OPENSSL_NO_SM2 */