summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2021-08-18 16:04:32 +0000
committertb <>2021-08-18 16:04:32 +0000
commit27a4a421da356671ca87fff69b8b7340d284659c (patch)
treeff95b8757df3a4b8d97a0f3f19a7c9962ba1076f
parente9cfb6e09338ad2081dfa06cdae4acc1dc0c78d9 (diff)
downloadopenbsd-27a4a421da356671ca87fff69b8b7340d284659c.tar.gz
openbsd-27a4a421da356671ca87fff69b8b7340d284659c.tar.bz2
openbsd-27a4a421da356671ca87fff69b8b7340d284659c.zip
Import initial code for the SM2 cipher
This adds the SM2 algorithm defined in the Chinese standards GB/T 32918.1-2016, GB/T 32918.2-2016, GB/T 32918.3-2016, GB/T 32918.4-2016 and GB/T 32918.5-2017. This is an ISC licensed implementation contributed by Ribose.inc, based on the same code that was contributed to OpenSSL by Jack Lloyd. The port to LibreSSL was done by Ronald Tse and Nickolay Olshevsky. Github PR #105 I made quite a few cleanup passes on this, but more is needed, some of which will happen in-tree before this is linked to the build. ok deraadt inoguchi (a long time ago), jsing
-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 */