2 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2017 Ribose Inc. All Rights Reserved.
4 * Ported from Ribose contributions from Botan.
6 * Licensed under the Apache License 2.0 (the "License"). You may not use
7 * this file except in compliance with the License. You can obtain a copy
8 * in the file LICENSE in the source distribution or at
9 * https://www.openssl.org/source/license.html
13 * ECDSA low level APIs are deprecated for public use, but still ok for
16 #include "internal/deprecated.h"
18 #include "crypto/sm2.h"
19 #include "crypto/sm2err.h"
20 #include "crypto/ec.h" /* ossl_ecdh_kdf_X9_63() */
21 #include <openssl/err.h>
22 #include <openssl/evp.h>
23 #include <openssl/bn.h>
24 #include <openssl/asn1.h>
25 #include <openssl/asn1t.h>
28 typedef struct SM2_Ciphertext_st SM2_Ciphertext
;
29 DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext
)
31 struct SM2_Ciphertext_st
{
34 ASN1_OCTET_STRING
*C3
;
35 ASN1_OCTET_STRING
*C2
;
38 ASN1_SEQUENCE(SM2_Ciphertext
) = {
39 ASN1_SIMPLE(SM2_Ciphertext
, C1x
, BIGNUM
),
40 ASN1_SIMPLE(SM2_Ciphertext
, C1y
, BIGNUM
),
41 ASN1_SIMPLE(SM2_Ciphertext
, C3
, ASN1_OCTET_STRING
),
42 ASN1_SIMPLE(SM2_Ciphertext
, C2
, ASN1_OCTET_STRING
),
43 } ASN1_SEQUENCE_END(SM2_Ciphertext
)
45 IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext
)
47 static size_t ec_field_size(const EC_GROUP
*group
)
49 /* Is there some simpler way to do this? */
53 size_t field_size
= 0;
55 if (p
== NULL
|| a
== NULL
|| b
== NULL
)
58 if (!EC_GROUP_get_curve(group
, p
, a
, b
, NULL
))
60 field_size
= (BN_num_bits(p
) + 7) / 8;
70 int ossl_sm2_plaintext_size(const unsigned char *ct
, size_t ct_size
,
73 struct SM2_Ciphertext_st
*sm2_ctext
= NULL
;
75 sm2_ctext
= d2i_SM2_Ciphertext(NULL
, &ct
, ct_size
);
77 if (sm2_ctext
== NULL
) {
78 ERR_raise(ERR_LIB_SM2
, SM2_R_INVALID_ENCODING
);
82 *pt_size
= sm2_ctext
->C2
->length
;
83 SM2_Ciphertext_free(sm2_ctext
);
88 int ossl_sm2_ciphertext_size(const EC_KEY
*key
, const EVP_MD
*digest
,
89 size_t msg_len
, size_t *ct_size
)
91 const size_t field_size
= ec_field_size(EC_KEY_get0_group(key
));
92 const int md_size
= EVP_MD_get_size(digest
);
95 if (field_size
== 0 || md_size
< 0)
98 /* Integer and string are simple type; set constructed = 0, means primitive and definite length encoding. */
99 sz
= 2 * ASN1_object_size(0, field_size
+ 1, V_ASN1_INTEGER
)
100 + ASN1_object_size(0, md_size
, V_ASN1_OCTET_STRING
)
101 + ASN1_object_size(0, msg_len
, V_ASN1_OCTET_STRING
);
102 /* Sequence is structured type; set constructed = 1, means constructed and definite length encoding. */
103 *ct_size
= ASN1_object_size(1, sz
, V_ASN1_SEQUENCE
);
108 int ossl_sm2_encrypt(const EC_KEY
*key
,
109 const EVP_MD
*digest
,
110 const uint8_t *msg
, size_t msg_len
,
111 uint8_t *ciphertext_buf
, size_t *ciphertext_len
)
113 int rc
= 0, ciphertext_leni
;
121 EVP_MD_CTX
*hash
= EVP_MD_CTX_new();
122 struct SM2_Ciphertext_st ctext_struct
;
123 const EC_GROUP
*group
= EC_KEY_get0_group(key
);
124 const BIGNUM
*order
= EC_GROUP_get0_order(group
);
125 const EC_POINT
*P
= EC_KEY_get0_public_key(key
);
128 uint8_t *msg_mask
= NULL
;
129 uint8_t *x2y2
= NULL
;
132 const int C3_size
= EVP_MD_get_size(digest
);
133 EVP_MD
*fetched_digest
= NULL
;
134 OSSL_LIB_CTX
*libctx
= ossl_ec_key_get_libctx(key
);
135 const char *propq
= ossl_ec_key_get0_propq(key
);
137 /* NULL these before any "goto done" */
138 ctext_struct
.C2
= NULL
;
139 ctext_struct
.C3
= NULL
;
141 if (hash
== NULL
|| C3_size
<= 0) {
142 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
146 field_size
= ec_field_size(group
);
147 if (field_size
== 0) {
148 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
152 kG
= EC_POINT_new(group
);
153 kP
= EC_POINT_new(group
);
154 ctx
= BN_CTX_new_ex(libctx
);
155 if (kG
== NULL
|| kP
== NULL
|| ctx
== NULL
) {
156 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
162 x1
= BN_CTX_get(ctx
);
163 x2
= BN_CTX_get(ctx
);
164 y1
= BN_CTX_get(ctx
);
165 y2
= BN_CTX_get(ctx
);
168 ERR_raise(ERR_LIB_SM2
, ERR_R_BN_LIB
);
172 x2y2
= OPENSSL_zalloc(2 * field_size
);
173 C3
= OPENSSL_zalloc(C3_size
);
175 if (x2y2
== NULL
|| C3
== NULL
) {
176 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
180 memset(ciphertext_buf
, 0, *ciphertext_len
);
182 if (!BN_priv_rand_range_ex(k
, order
, 0, ctx
)) {
183 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
187 if (!EC_POINT_mul(group
, kG
, k
, NULL
, NULL
, ctx
)
188 || !EC_POINT_get_affine_coordinates(group
, kG
, x1
, y1
, ctx
)
189 || !EC_POINT_mul(group
, kP
, NULL
, P
, k
, ctx
)
190 || !EC_POINT_get_affine_coordinates(group
, kP
, x2
, y2
, ctx
)) {
191 ERR_raise(ERR_LIB_SM2
, ERR_R_EC_LIB
);
195 if (BN_bn2binpad(x2
, x2y2
, field_size
) < 0
196 || BN_bn2binpad(y2
, x2y2
+ field_size
, field_size
) < 0) {
197 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
201 msg_mask
= OPENSSL_zalloc(msg_len
);
202 if (msg_mask
== NULL
) {
203 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
207 /* X9.63 with no salt happens to match the KDF used in SM2 */
208 if (!ossl_ecdh_kdf_X9_63(msg_mask
, msg_len
, x2y2
, 2 * field_size
, NULL
, 0,
209 digest
, libctx
, propq
)) {
210 ERR_raise(ERR_LIB_SM2
, ERR_R_EVP_LIB
);
214 for (i
= 0; i
!= msg_len
; ++i
)
215 msg_mask
[i
] ^= msg
[i
];
217 fetched_digest
= EVP_MD_fetch(libctx
, EVP_MD_get0_name(digest
), propq
);
218 if (fetched_digest
== NULL
) {
219 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
222 if (EVP_DigestInit(hash
, fetched_digest
) == 0
223 || EVP_DigestUpdate(hash
, x2y2
, field_size
) == 0
224 || EVP_DigestUpdate(hash
, msg
, msg_len
) == 0
225 || EVP_DigestUpdate(hash
, x2y2
+ field_size
, field_size
) == 0
226 || EVP_DigestFinal(hash
, C3
, NULL
) == 0) {
227 ERR_raise(ERR_LIB_SM2
, ERR_R_EVP_LIB
);
231 ctext_struct
.C1x
= x1
;
232 ctext_struct
.C1y
= y1
;
233 ctext_struct
.C3
= ASN1_OCTET_STRING_new();
234 ctext_struct
.C2
= ASN1_OCTET_STRING_new();
236 if (ctext_struct
.C3
== NULL
|| ctext_struct
.C2
== NULL
) {
237 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
240 if (!ASN1_OCTET_STRING_set(ctext_struct
.C3
, C3
, C3_size
)
241 || !ASN1_OCTET_STRING_set(ctext_struct
.C2
, msg_mask
, msg_len
)) {
242 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
246 ciphertext_leni
= i2d_SM2_Ciphertext(&ctext_struct
, &ciphertext_buf
);
247 /* Ensure cast to size_t is safe */
248 if (ciphertext_leni
< 0) {
249 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
252 *ciphertext_len
= (size_t)ciphertext_leni
;
257 EVP_MD_free(fetched_digest
);
258 ASN1_OCTET_STRING_free(ctext_struct
.C2
);
259 ASN1_OCTET_STRING_free(ctext_struct
.C3
);
260 OPENSSL_free(msg_mask
);
263 EVP_MD_CTX_free(hash
);
270 int ossl_sm2_decrypt(const EC_KEY
*key
,
271 const EVP_MD
*digest
,
272 const uint8_t *ciphertext
, size_t ciphertext_len
,
273 uint8_t *ptext_buf
, size_t *ptext_len
)
278 const EC_GROUP
*group
= EC_KEY_get0_group(key
);
280 struct SM2_Ciphertext_st
*sm2_ctext
= NULL
;
283 uint8_t *x2y2
= NULL
;
284 uint8_t *computed_C3
= NULL
;
285 const size_t field_size
= ec_field_size(group
);
286 const int hash_size
= EVP_MD_get_size(digest
);
287 uint8_t *msg_mask
= NULL
;
288 const uint8_t *C2
= NULL
;
289 const uint8_t *C3
= NULL
;
291 EVP_MD_CTX
*hash
= NULL
;
292 OSSL_LIB_CTX
*libctx
= ossl_ec_key_get_libctx(key
);
293 const char *propq
= ossl_ec_key_get0_propq(key
);
295 if (field_size
== 0 || hash_size
<= 0)
298 memset(ptext_buf
, 0xFF, *ptext_len
);
300 sm2_ctext
= d2i_SM2_Ciphertext(NULL
, &ciphertext
, ciphertext_len
);
302 if (sm2_ctext
== NULL
) {
303 ERR_raise(ERR_LIB_SM2
, SM2_R_ASN1_ERROR
);
307 if (sm2_ctext
->C3
->length
!= hash_size
) {
308 ERR_raise(ERR_LIB_SM2
, SM2_R_INVALID_ENCODING
);
312 C2
= sm2_ctext
->C2
->data
;
313 C3
= sm2_ctext
->C3
->data
;
314 msg_len
= sm2_ctext
->C2
->length
;
316 ctx
= BN_CTX_new_ex(libctx
);
318 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
323 x2
= BN_CTX_get(ctx
);
324 y2
= BN_CTX_get(ctx
);
327 ERR_raise(ERR_LIB_SM2
, ERR_R_BN_LIB
);
331 msg_mask
= OPENSSL_zalloc(msg_len
);
332 x2y2
= OPENSSL_zalloc(2 * field_size
);
333 computed_C3
= OPENSSL_zalloc(hash_size
);
335 if (msg_mask
== NULL
|| x2y2
== NULL
|| computed_C3
== NULL
) {
336 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
340 C1
= EC_POINT_new(group
);
342 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
346 if (!EC_POINT_set_affine_coordinates(group
, C1
, sm2_ctext
->C1x
,
348 || !EC_POINT_mul(group
, C1
, NULL
, C1
, EC_KEY_get0_private_key(key
),
350 || !EC_POINT_get_affine_coordinates(group
, C1
, x2
, y2
, ctx
)) {
351 ERR_raise(ERR_LIB_SM2
, ERR_R_EC_LIB
);
355 if (BN_bn2binpad(x2
, x2y2
, field_size
) < 0
356 || BN_bn2binpad(y2
, x2y2
+ field_size
, field_size
) < 0
357 || !ossl_ecdh_kdf_X9_63(msg_mask
, msg_len
, x2y2
, 2 * field_size
,
358 NULL
, 0, digest
, libctx
, propq
)) {
359 ERR_raise(ERR_LIB_SM2
, ERR_R_INTERNAL_ERROR
);
363 for (i
= 0; i
!= msg_len
; ++i
)
364 ptext_buf
[i
] = C2
[i
] ^ msg_mask
[i
];
366 hash
= EVP_MD_CTX_new();
368 ERR_raise(ERR_LIB_SM2
, ERR_R_MALLOC_FAILURE
);
372 if (!EVP_DigestInit(hash
, digest
)
373 || !EVP_DigestUpdate(hash
, x2y2
, field_size
)
374 || !EVP_DigestUpdate(hash
, ptext_buf
, msg_len
)
375 || !EVP_DigestUpdate(hash
, x2y2
+ field_size
, field_size
)
376 || !EVP_DigestFinal(hash
, computed_C3
, NULL
)) {
377 ERR_raise(ERR_LIB_SM2
, ERR_R_EVP_LIB
);
381 if (CRYPTO_memcmp(computed_C3
, C3
, hash_size
) != 0) {
382 ERR_raise(ERR_LIB_SM2
, SM2_R_INVALID_DIGEST
);
387 *ptext_len
= msg_len
;
391 memset(ptext_buf
, 0, *ptext_len
);
393 OPENSSL_free(msg_mask
);
395 OPENSSL_free(computed_C3
);
398 SM2_Ciphertext_free(sm2_ctext
);
399 EVP_MD_CTX_free(hash
);