2 * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2017 Ribose Inc. All Rights Reserved.
4 * Ported from Ribose contributions from Botan.
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
12 #include "internal/sm2.h"
13 #include "internal/sm2err.h"
14 #include <openssl/err.h>
15 #include <openssl/evp.h>
16 #include <openssl/bn.h>
17 #include <openssl/asn1.h>
18 #include <openssl/asn1t.h>
21 typedef struct SM2_Ciphertext_st SM2_Ciphertext
;
22 DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext
)
24 struct SM2_Ciphertext_st
{
27 ASN1_OCTET_STRING
*C3
;
28 ASN1_OCTET_STRING
*C2
;
31 ASN1_SEQUENCE(SM2_Ciphertext
) = {
32 ASN1_SIMPLE(SM2_Ciphertext
, C1x
, BIGNUM
),
33 ASN1_SIMPLE(SM2_Ciphertext
, C1y
, BIGNUM
),
34 ASN1_SIMPLE(SM2_Ciphertext
, C3
, ASN1_OCTET_STRING
),
35 ASN1_SIMPLE(SM2_Ciphertext
, C2
, ASN1_OCTET_STRING
),
36 } ASN1_SEQUENCE_END(SM2_Ciphertext
)
38 IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext
)
40 static size_t EC_field_size(const EC_GROUP
*group
)
42 /* Is there some simpler way to do this? */
46 size_t field_size
= 0;
48 if (p
== NULL
|| a
== NULL
|| b
== NULL
)
51 EC_GROUP_get_curve_GFp(group
, p
, a
, b
, NULL
);
52 field_size
= (BN_num_bits(p
) + 7) / 8;
62 int SM2_plaintext_size(const EC_KEY
*key
, const EVP_MD
*digest
, size_t msg_len
,
65 const size_t field_size
= EC_field_size(EC_KEY_get0_group(key
));
66 const int md_size
= EVP_MD_size(digest
);
70 SM2err(SM2_F_SM2_ENCRYPT
, SM2_R_INVALID_DIGEST
);
73 if (field_size
== 0) {
74 SM2err(SM2_F_SM2_ENCRYPT
, SM2_R_INVALID_FIELD
);
78 overhead
= 10 + 2 * field_size
+ (size_t)md_size
;
79 if(msg_len
<= overhead
) {
80 SM2err(SM2_F_SM2_ENCRYPT
, SM2_R_INVALID_ENCODING
);
84 *pt_size
= msg_len
- overhead
;
88 int SM2_ciphertext_size(const EC_KEY
*key
, const EVP_MD
*digest
, size_t msg_len
,
91 const size_t field_size
= EC_field_size(EC_KEY_get0_group(key
));
92 const int md_size
= EVP_MD_size(digest
);
94 if (field_size
== 0 || md_size
< 0)
97 *ct_size
= 10 + 2 * field_size
+ (size_t)md_size
+ msg_len
;
101 int SM2_encrypt(const EC_KEY
*key
,
102 const EVP_MD
*digest
,
104 size_t msg_len
, uint8_t *ciphertext_buf
, size_t *ciphertext_len
)
106 int rc
= 0, ciphertext_leni
;
114 EVP_MD_CTX
*hash
= EVP_MD_CTX_new();
115 struct SM2_Ciphertext_st ctext_struct
;
116 const EC_GROUP
*group
= EC_KEY_get0_group(key
);
117 const BIGNUM
*order
= EC_GROUP_get0_order(group
);
118 const EC_POINT
*P
= EC_KEY_get0_public_key(key
);
121 uint8_t *msg_mask
= NULL
;
122 uint8_t *x2y2
= NULL
;
124 const size_t field_size
= EC_field_size(group
);
125 const size_t C3_size
= EVP_MD_size(digest
);
127 /* NULL these before any "goto done" */
128 ctext_struct
.C2
= NULL
;
129 ctext_struct
.C3
= NULL
;
137 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_INTERNAL_ERROR
);
141 kG
= EC_POINT_new(group
);
142 kP
= EC_POINT_new(group
);
144 if (kG
== NULL
|| kP
== NULL
|| ctx
== NULL
) {
145 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_MALLOC_FAILURE
);
151 x1
= BN_CTX_get(ctx
);
152 x2
= BN_CTX_get(ctx
);
153 y1
= BN_CTX_get(ctx
);
154 y2
= BN_CTX_get(ctx
);
157 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_BN_LIB
);
161 x2y2
= OPENSSL_zalloc(2 * field_size
);
162 C3
= OPENSSL_zalloc(C3_size
);
164 if (x2y2
== NULL
|| C3
== NULL
) {
165 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_MALLOC_FAILURE
);
169 memset(ciphertext_buf
, 0, *ciphertext_len
);
171 if (!BN_priv_rand_range(k
, order
)) {
172 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_INTERNAL_ERROR
);
176 if (!EC_POINT_mul(group
, kG
, k
, NULL
, NULL
, ctx
)
177 || !EC_POINT_get_affine_coordinates_GFp(group
, kG
, x1
, y1
, ctx
)
178 || !EC_POINT_mul(group
, kP
, NULL
, P
, k
, ctx
)
179 || !EC_POINT_get_affine_coordinates_GFp(group
, kP
, x2
, y2
, ctx
)) {
180 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_EC_LIB
);
184 if (BN_bn2binpad(x2
, x2y2
, field_size
) < 0
185 || BN_bn2binpad(y2
, x2y2
+ field_size
, field_size
) < 0) {
186 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_INTERNAL_ERROR
);
190 msg_mask
= OPENSSL_zalloc(msg_len
);
191 if (msg_mask
== NULL
) {
192 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_MALLOC_FAILURE
);
196 /* X9.63 with no salt happens to match the KDF used in SM2 */
197 if (!ECDH_KDF_X9_62(msg_mask
, msg_len
, x2y2
, 2 * field_size
, NULL
, 0,
199 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_EVP_LIB
);
203 for (i
= 0; i
!= msg_len
; ++i
)
204 msg_mask
[i
] ^= msg
[i
];
206 if (EVP_DigestInit(hash
, digest
) == 0
207 || EVP_DigestUpdate(hash
, x2y2
, field_size
) == 0
208 || EVP_DigestUpdate(hash
, msg
, msg_len
) == 0
209 || EVP_DigestUpdate(hash
, x2y2
+ field_size
, field_size
) == 0
210 || EVP_DigestFinal(hash
, C3
, NULL
) == 0) {
211 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_EVP_LIB
);
215 ctext_struct
.C1x
= x1
;
216 ctext_struct
.C1y
= y1
;
217 ctext_struct
.C3
= ASN1_OCTET_STRING_new();
218 ctext_struct
.C2
= ASN1_OCTET_STRING_new();
220 if (ctext_struct
.C3
== NULL
|| ctext_struct
.C2
== NULL
) {
221 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_MALLOC_FAILURE
);
224 if (!ASN1_OCTET_STRING_set(ctext_struct
.C3
, C3
, C3_size
)
225 || !ASN1_OCTET_STRING_set(ctext_struct
.C2
, msg_mask
, msg_len
)) {
226 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_INTERNAL_ERROR
);
230 ciphertext_leni
= i2d_SM2_Ciphertext(&ctext_struct
, &ciphertext_buf
);
231 /* Ensure cast to size_t is safe */
232 if (ciphertext_leni
< 0) {
233 SM2err(SM2_F_SM2_ENCRYPT
, ERR_R_INTERNAL_ERROR
);
236 *ciphertext_len
= (size_t)ciphertext_leni
;
241 ASN1_OCTET_STRING_free(ctext_struct
.C2
);
242 ASN1_OCTET_STRING_free(ctext_struct
.C3
);
243 OPENSSL_free(msg_mask
);
246 EVP_MD_CTX_free(hash
);
253 int SM2_decrypt(const EC_KEY
*key
,
254 const EVP_MD
*digest
,
255 const uint8_t *ciphertext
,
256 size_t ciphertext_len
, uint8_t *ptext_buf
, size_t *ptext_len
)
262 const EC_GROUP
*group
= EC_KEY_get0_group(key
);
264 struct SM2_Ciphertext_st
*sm2_ctext
= NULL
;
268 uint8_t *x2y2
= NULL
;
269 uint8_t *computed_C3
= NULL
;
271 const size_t field_size
= EC_field_size(group
);
272 const int hash_size
= EVP_MD_size(digest
);
274 uint8_t *msg_mask
= NULL
;
275 const uint8_t *C2
= NULL
;
276 const uint8_t *C3
= NULL
;
278 EVP_MD_CTX
*hash
= NULL
;
280 if (field_size
== 0 || hash_size
== 0)
283 memset(ptext_buf
, 0xFF, *ptext_len
);
285 sm2_ctext
= d2i_SM2_Ciphertext(NULL
, &ciphertext
, ciphertext_len
);
287 if (sm2_ctext
== NULL
)
289 SM2err(SM2_F_SM2_DECRYPT
, SM2_R_ASN1_ERROR
);
293 if (sm2_ctext
->C3
->length
!= hash_size
)
295 SM2err(SM2_F_SM2_DECRYPT
, SM2_R_INVALID_ENCODING
);
299 C2
= sm2_ctext
->C2
->data
;
300 C3
= sm2_ctext
->C3
->data
;
301 msg_len
= sm2_ctext
->C2
->length
;
306 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_MALLOC_FAILURE
);
311 x2
= BN_CTX_get(ctx
);
312 y2
= BN_CTX_get(ctx
);
316 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_BN_LIB
);
320 msg_mask
= OPENSSL_zalloc(msg_len
);
321 x2y2
= OPENSSL_zalloc(2 * field_size
);
322 computed_C3
= OPENSSL_zalloc(hash_size
);
324 if(msg_mask
== NULL
|| x2y2
== NULL
|| computed_C3
== NULL
)
326 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_MALLOC_FAILURE
);
330 C1
= EC_POINT_new(group
);
333 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_MALLOC_FAILURE
);
337 if (EC_POINT_set_affine_coordinates_GFp
338 (group
, C1
, sm2_ctext
->C1x
, sm2_ctext
->C1y
, ctx
) == 0)
340 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EC_LIB
);
344 if (EC_POINT_mul(group
, C1
, NULL
, C1
, EC_KEY_get0_private_key(key
), ctx
) ==
347 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EC_LIB
);
351 if (EC_POINT_get_affine_coordinates_GFp(group
, C1
, x2
, y2
, ctx
) == 0)
353 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EC_LIB
);
357 BN_bn2binpad(x2
, x2y2
, field_size
);
358 BN_bn2binpad(y2
, x2y2
+ field_size
, field_size
);
360 if (ECDH_KDF_X9_62(msg_mask
, msg_len
, x2y2
, 2 * field_size
, NULL
, 0, digest
)
364 for (i
= 0; i
!= msg_len
; ++i
)
365 ptext_buf
[i
] = C2
[i
] ^ msg_mask
[i
];
367 hash
= EVP_MD_CTX_new();
371 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_MALLOC_FAILURE
);
375 if (EVP_DigestInit(hash
, digest
) == 0)
377 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EVP_LIB
);
381 if (EVP_DigestUpdate(hash
, x2y2
, field_size
) == 0)
383 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EVP_LIB
);
387 if (EVP_DigestUpdate(hash
, ptext_buf
, msg_len
) == 0)
389 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EVP_LIB
);
393 if (EVP_DigestUpdate(hash
, x2y2
+ field_size
, field_size
) == 0)
395 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EVP_LIB
);
399 if (EVP_DigestFinal(hash
, computed_C3
, NULL
) == 0)
401 SM2err(SM2_F_SM2_DECRYPT
, ERR_R_EVP_LIB
);
405 if (memcmp(computed_C3
, C3
, hash_size
) != 0)
409 *ptext_len
= msg_len
;
414 memset(ptext_buf
, 0, *ptext_len
);
416 OPENSSL_free(msg_mask
);
418 OPENSSL_free(computed_C3
);
421 SM2_Ciphertext_free(sm2_ctext
);
422 EVP_MD_CTX_free(hash
);