Following the license change, modify the boilerplates in crypto/smN/
[openssl.git] / crypto / sm2 / sm2_crypt.c
1 /*
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.
5  *
6  * Licensed under the Apache License 2.0 (the "License").  You may not use
7  * this file except in compliance with the License.  You can obtain a copy
8  * in the file LICENSE in the source distribution or at
9  * https://www.openssl.org/source/license.html
10  */
11
12 #include "internal/sm2.h"
13 #include "internal/sm2err.h"
14 #include "internal/ec_int.h" /* ecdh_KDF_X9_63() */
15 #include <openssl/err.h>
16 #include <openssl/evp.h>
17 #include <openssl/bn.h>
18 #include <openssl/asn1.h>
19 #include <openssl/asn1t.h>
20 #include <string.h>
21
22 typedef struct SM2_Ciphertext_st SM2_Ciphertext;
23 DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext)
24
25 struct SM2_Ciphertext_st {
26     BIGNUM *C1x;
27     BIGNUM *C1y;
28     ASN1_OCTET_STRING *C3;
29     ASN1_OCTET_STRING *C2;
30 };
31
32 ASN1_SEQUENCE(SM2_Ciphertext) = {
33     ASN1_SIMPLE(SM2_Ciphertext, C1x, BIGNUM),
34     ASN1_SIMPLE(SM2_Ciphertext, C1y, BIGNUM),
35     ASN1_SIMPLE(SM2_Ciphertext, C3, ASN1_OCTET_STRING),
36     ASN1_SIMPLE(SM2_Ciphertext, C2, ASN1_OCTET_STRING),
37 } ASN1_SEQUENCE_END(SM2_Ciphertext)
38
39 IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext)
40
41 static size_t ec_field_size(const EC_GROUP *group)
42 {
43     /* Is there some simpler way to do this? */
44     BIGNUM *p = BN_new();
45     BIGNUM *a = BN_new();
46     BIGNUM *b = BN_new();
47     size_t field_size = 0;
48
49     if (p == NULL || a == NULL || b == NULL)
50        goto done;
51
52     if (!EC_GROUP_get_curve(group, p, a, b, NULL))
53         goto done;
54     field_size = (BN_num_bits(p) + 7) / 8;
55
56  done:
57     BN_free(p);
58     BN_free(a);
59     BN_free(b);
60
61     return field_size;
62 }
63
64 int sm2_plaintext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
65                        size_t *pt_size)
66 {
67     const size_t field_size = ec_field_size(EC_KEY_get0_group(key));
68     const int md_size = EVP_MD_size(digest);
69     size_t overhead;
70
71     if (md_size < 0) {
72         SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_DIGEST);
73         return 0;
74     }
75     if (field_size == 0) {
76         SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_FIELD);
77         return 0;
78     }
79
80     overhead = 10 + 2 * field_size + (size_t)md_size;
81     if (msg_len <= overhead) {
82         SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_ENCODING);
83         return 0;
84     }
85
86     *pt_size = msg_len - overhead;
87     return 1;
88 }
89
90 int sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
91                         size_t *ct_size)
92 {
93     const size_t field_size = ec_field_size(EC_KEY_get0_group(key));
94     const int md_size = EVP_MD_size(digest);
95     size_t sz;
96
97     if (field_size == 0 || md_size < 0)
98         return 0;
99
100     /* Integer and string are simple type; set constructed = 0, means primitive and definite length encoding. */
101     sz = 2 * ASN1_object_size(0, field_size + 1, V_ASN1_INTEGER)
102          + ASN1_object_size(0, md_size, V_ASN1_OCTET_STRING)
103          + ASN1_object_size(0, msg_len, V_ASN1_OCTET_STRING);
104     /* Sequence is structured type; set constructed = 1, means constructed and definite length encoding. */
105     *ct_size = ASN1_object_size(1, sz, V_ASN1_SEQUENCE);
106
107     return 1;
108 }
109
110 int sm2_encrypt(const EC_KEY *key,
111                 const EVP_MD *digest,
112                 const uint8_t *msg,
113                 size_t msg_len, uint8_t *ciphertext_buf, size_t *ciphertext_len)
114 {
115     int rc = 0, ciphertext_leni;
116     size_t i;
117     BN_CTX *ctx = NULL;
118     BIGNUM *k = NULL;
119     BIGNUM *x1 = NULL;
120     BIGNUM *y1 = NULL;
121     BIGNUM *x2 = NULL;
122     BIGNUM *y2 = NULL;
123     EVP_MD_CTX *hash = EVP_MD_CTX_new();
124     struct SM2_Ciphertext_st ctext_struct;
125     const EC_GROUP *group = EC_KEY_get0_group(key);
126     const BIGNUM *order = EC_GROUP_get0_order(group);
127     const EC_POINT *P = EC_KEY_get0_public_key(key);
128     EC_POINT *kG = NULL;
129     EC_POINT *kP = NULL;
130     uint8_t *msg_mask = NULL;
131     uint8_t *x2y2 = NULL;
132     uint8_t *C3 = NULL;
133     size_t field_size;
134     const int C3_size = EVP_MD_size(digest);
135
136     /* NULL these before any "goto done" */
137     ctext_struct.C2 = NULL;
138     ctext_struct.C3 = NULL;
139
140     if (hash == NULL || C3_size <= 0) {
141         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
142         goto done;
143     }
144
145     field_size = ec_field_size(group);
146     if (field_size == 0) {
147         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
148         goto done;
149     }
150
151     kG = EC_POINT_new(group);
152     kP = EC_POINT_new(group);
153     ctx = BN_CTX_new();
154     if (kG == NULL || kP == NULL || ctx == NULL) {
155         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
156         goto done;
157     }
158
159     BN_CTX_start(ctx);
160     k = BN_CTX_get(ctx);
161     x1 = BN_CTX_get(ctx);
162     x2 = BN_CTX_get(ctx);
163     y1 = BN_CTX_get(ctx);
164     y2 = BN_CTX_get(ctx);
165
166     if (y2 == NULL) {
167         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_BN_LIB);
168         goto done;
169     }
170
171     x2y2 = OPENSSL_zalloc(2 * field_size);
172     C3 = OPENSSL_zalloc(C3_size);
173
174     if (x2y2 == NULL || C3 == NULL) {
175         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
176         goto done;
177     }
178
179     memset(ciphertext_buf, 0, *ciphertext_len);
180
181     if (!BN_priv_rand_range(k, order)) {
182         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
183         goto done;
184     }
185
186     if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
187             || !EC_POINT_get_affine_coordinates(group, kG, x1, y1, ctx)
188             || !EC_POINT_mul(group, kP, NULL, P, k, ctx)
189             || !EC_POINT_get_affine_coordinates(group, kP, x2, y2, ctx)) {
190         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EC_LIB);
191         goto done;
192     }
193
194     if (BN_bn2binpad(x2, x2y2, field_size) < 0
195             || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0) {
196         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
197         goto done;
198     }
199
200     msg_mask = OPENSSL_zalloc(msg_len);
201     if (msg_mask == NULL) {
202        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
203        goto done;
204    }
205
206     /* X9.63 with no salt happens to match the KDF used in SM2 */
207     if (!ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
208                         digest)) {
209         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
210         goto done;
211     }
212
213     for (i = 0; i != msg_len; ++i)
214         msg_mask[i] ^= msg[i];
215
216     if (EVP_DigestInit(hash, digest) == 0
217             || EVP_DigestUpdate(hash, x2y2, field_size) == 0
218             || EVP_DigestUpdate(hash, msg, msg_len) == 0
219             || EVP_DigestUpdate(hash, x2y2 + field_size, field_size) == 0
220             || EVP_DigestFinal(hash, C3, NULL) == 0) {
221         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
222         goto done;
223     }
224
225     ctext_struct.C1x = x1;
226     ctext_struct.C1y = y1;
227     ctext_struct.C3 = ASN1_OCTET_STRING_new();
228     ctext_struct.C2 = ASN1_OCTET_STRING_new();
229
230     if (ctext_struct.C3 == NULL || ctext_struct.C2 == NULL) {
231        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
232        goto done;
233     }
234     if (!ASN1_OCTET_STRING_set(ctext_struct.C3, C3, C3_size)
235             || !ASN1_OCTET_STRING_set(ctext_struct.C2, msg_mask, msg_len)) {
236         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
237         goto done;
238     }
239
240     ciphertext_leni = i2d_SM2_Ciphertext(&ctext_struct, &ciphertext_buf);
241     /* Ensure cast to size_t is safe */
242     if (ciphertext_leni < 0) {
243         SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
244         goto done;
245     }
246     *ciphertext_len = (size_t)ciphertext_leni;
247
248     rc = 1;
249
250  done:
251     ASN1_OCTET_STRING_free(ctext_struct.C2);
252     ASN1_OCTET_STRING_free(ctext_struct.C3);
253     OPENSSL_free(msg_mask);
254     OPENSSL_free(x2y2);
255     OPENSSL_free(C3);
256     EVP_MD_CTX_free(hash);
257     BN_CTX_free(ctx);
258     EC_POINT_free(kG);
259     EC_POINT_free(kP);
260     return rc;
261 }
262
263 int sm2_decrypt(const EC_KEY *key,
264                 const EVP_MD *digest,
265                 const uint8_t *ciphertext,
266                 size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len)
267 {
268     int rc = 0;
269     int i;
270     BN_CTX *ctx = NULL;
271     const EC_GROUP *group = EC_KEY_get0_group(key);
272     EC_POINT *C1 = NULL;
273     struct SM2_Ciphertext_st *sm2_ctext = NULL;
274     BIGNUM *x2 = NULL;
275     BIGNUM *y2 = NULL;
276     uint8_t *x2y2 = NULL;
277     uint8_t *computed_C3 = NULL;
278     const size_t field_size = ec_field_size(group);
279     const int hash_size = EVP_MD_size(digest);
280     uint8_t *msg_mask = NULL;
281     const uint8_t *C2 = NULL;
282     const uint8_t *C3 = NULL;
283     int msg_len = 0;
284     EVP_MD_CTX *hash = NULL;
285
286     if (field_size == 0 || hash_size <= 0)
287        goto done;
288
289     memset(ptext_buf, 0xFF, *ptext_len);
290
291     sm2_ctext = d2i_SM2_Ciphertext(NULL, &ciphertext, ciphertext_len);
292
293     if (sm2_ctext == NULL) {
294         SM2err(SM2_F_SM2_DECRYPT, SM2_R_ASN1_ERROR);
295         goto done;
296     }
297
298     if (sm2_ctext->C3->length != hash_size) {
299         SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_ENCODING);
300         goto done;
301     }
302
303     C2 = sm2_ctext->C2->data;
304     C3 = sm2_ctext->C3->data;
305     msg_len = sm2_ctext->C2->length;
306
307     ctx = BN_CTX_new();
308     if (ctx == NULL) {
309         SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
310         goto done;
311     }
312
313     BN_CTX_start(ctx);
314     x2 = BN_CTX_get(ctx);
315     y2 = BN_CTX_get(ctx);
316
317     if (y2 == NULL) {
318         SM2err(SM2_F_SM2_DECRYPT, ERR_R_BN_LIB);
319         goto done;
320     }
321
322     msg_mask = OPENSSL_zalloc(msg_len);
323     x2y2 = OPENSSL_zalloc(2 * field_size);
324     computed_C3 = OPENSSL_zalloc(hash_size);
325
326     if (msg_mask == NULL || x2y2 == NULL || computed_C3 == NULL) {
327         SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
328         goto done;
329     }
330
331     C1 = EC_POINT_new(group);
332     if (C1 == NULL) {
333         SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
334         goto done;
335     }
336
337     if (!EC_POINT_set_affine_coordinates(group, C1, sm2_ctext->C1x,
338                                          sm2_ctext->C1y, ctx)
339             || !EC_POINT_mul(group, C1, NULL, C1, EC_KEY_get0_private_key(key),
340                              ctx)
341             || !EC_POINT_get_affine_coordinates(group, C1, x2, y2, ctx)) {
342         SM2err(SM2_F_SM2_DECRYPT, ERR_R_EC_LIB);
343         goto done;
344     }
345
346     if (BN_bn2binpad(x2, x2y2, field_size) < 0
347             || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0
348             || !ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
349                                digest)) {
350         SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR);
351         goto done;
352     }
353
354     for (i = 0; i != msg_len; ++i)
355         ptext_buf[i] = C2[i] ^ msg_mask[i];
356
357     hash = EVP_MD_CTX_new();
358     if (hash == NULL) {
359         SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
360         goto done;
361     }
362
363     if (!EVP_DigestInit(hash, digest)
364             || !EVP_DigestUpdate(hash, x2y2, field_size)
365             || !EVP_DigestUpdate(hash, ptext_buf, msg_len)
366             || !EVP_DigestUpdate(hash, x2y2 + field_size, field_size)
367             || !EVP_DigestFinal(hash, computed_C3, NULL)) {
368         SM2err(SM2_F_SM2_DECRYPT, ERR_R_EVP_LIB);
369         goto done;
370     }
371
372     if (CRYPTO_memcmp(computed_C3, C3, hash_size) != 0) {
373         SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_DIGEST);
374         goto done;
375     }
376
377     rc = 1;
378     *ptext_len = msg_len;
379
380  done:
381     if (rc == 0)
382         memset(ptext_buf, 0, *ptext_len);
383
384     OPENSSL_free(msg_mask);
385     OPENSSL_free(x2y2);
386     OPENSSL_free(computed_C3);
387     EC_POINT_free(C1);
388     BN_CTX_free(ctx);
389     SM2_Ciphertext_free(sm2_ctext);
390     EVP_MD_CTX_free(hash);
391
392     return rc;
393 }