1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_SM2_SIGN) || defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_ECDSA) || \
18 defined(HITLS_CRYPTO_SM2_CRYPT)
19 #include "securec.h"
20 #include "crypt_errno.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_obj_internal.h"
23 #include "crypt_encode_internal.h"
24 #include "bsl_asn1.h"
25
26 /**
27 * Common function to encode ASN.1 template and copy result
28 */
EncodeAsn1Template(BSL_ASN1_Template * templ,BSL_ASN1_Buffer * asnArr,uint32_t asnArrLen,uint8_t * encode,uint32_t * encodeLen)29 static int32_t EncodeAsn1Template(BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr, uint32_t asnArrLen,
30 uint8_t *encode, uint32_t *encodeLen)
31 {
32 uint8_t *outBuf = NULL;
33 uint32_t outLen = 0;
34
35 int32_t ret = BSL_ASN1_EncodeTemplate(templ, asnArr, asnArrLen, &outBuf, &outLen);
36 if (ret != CRYPT_SUCCESS) {
37 BSL_ERR_PUSH_ERROR(ret);
38 return ret;
39 }
40
41 if (outLen > *encodeLen) {
42 BSL_SAL_Free(outBuf);
43 BSL_ERR_PUSH_ERROR(CRYPT_ENCODE_BUFF_NOT_ENOUGH);
44 return CRYPT_ENCODE_BUFF_NOT_ENOUGH;
45 }
46
47 (void)memcpy_s(encode, *encodeLen, outBuf, outLen);
48 BSL_SAL_Free(outBuf);
49 *encodeLen = outLen;
50
51 return CRYPT_SUCCESS;
52 }
53
54 /**
55 * Common function to decode ASN.1 template and check remaining length
56 */
DecodeAsn1Template(const uint8_t * encode,uint32_t encodeLen,BSL_ASN1_Template * templ,BSL_ASN1_Buffer * asnArr,uint32_t asnArrLen)57 static int32_t DecodeAsn1Template(const uint8_t *encode, uint32_t encodeLen, BSL_ASN1_Template *templ,
58 BSL_ASN1_Buffer *asnArr, uint32_t asnArrLen)
59 {
60 uint8_t *tmpEnc = (uint8_t *)(uintptr_t)encode;
61 uint32_t tmpEncLen = encodeLen;
62
63 int32_t ret = BSL_ASN1_DecodeTemplate(templ, NULL, &tmpEnc, &tmpEncLen, asnArr, asnArrLen);
64 if (ret != CRYPT_SUCCESS) {
65 BSL_ERR_PUSH_ERROR(ret);
66 return ret;
67 }
68
69 if (tmpEncLen != 0) {
70 BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ASN1_BUFF_FAILED);
71 return CRYPT_DECODE_ASN1_BUFF_FAILED;
72 }
73
74 for (uint32_t i = 0; i < asnArrLen; i++) {
75 if (asnArr[i].len == 0) {
76 BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ASN1_BUFF_LEN_ZERO);
77 return CRYPT_DECODE_ASN1_BUFF_LEN_ZERO;
78 }
79 }
80
81 return CRYPT_SUCCESS;
82 }
83
84 #if defined(HITLS_CRYPTO_SM2_SIGN) || defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_ECDSA)
CRYPT_EAL_GetSignEncodeLen(uint32_t rLen,uint32_t sLen,uint32_t * maxLen)85 int32_t CRYPT_EAL_GetSignEncodeLen(uint32_t rLen, uint32_t sLen, uint32_t *maxLen)
86 {
87 /**
88 * https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-integer
89 * If the integer is positive but the high order bit is set to 1,
90 * a leading 0x00 is added to the content to indicate that the number is not negative
91 */
92 if (rLen == 0 || rLen > UINT32_MAX - 1 || sLen == 0 || sLen > UINT32_MAX - 1 || maxLen == NULL) {
93 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
94 return CRYPT_INVALID_ARG;
95 }
96 uint32_t rEncodeLen = 0;
97 uint32_t sEncodeLen = 0;
98 int32_t ret = BSL_ASN1_GetEncodeLen(rLen + 1, &rEncodeLen); // + 1: if high bit is 1, should add a leading 0x00
99 if (ret != CRYPT_SUCCESS) {
100 BSL_ERR_PUSH_ERROR(ret);
101 return ret;
102 }
103 ret = BSL_ASN1_GetEncodeLen(sLen + 1, &sEncodeLen); // + 1: if high bit is 1, should add a leading 0x00
104 if (ret != CRYPT_SUCCESS) {
105 BSL_ERR_PUSH_ERROR(ret);
106 return ret;
107 }
108
109 if (rEncodeLen > UINT32_MAX - sEncodeLen) {
110 BSL_ERR_PUSH_ERROR(CRYPT_ENCODE_ERR_SIGN_LEN_OVERFLOW);
111 return CRYPT_ENCODE_ERR_SIGN_LEN_OVERFLOW;
112 }
113 ret = BSL_ASN1_GetEncodeLen(rEncodeLen + sEncodeLen, maxLen);
114 if (ret != CRYPT_SUCCESS) {
115 BSL_ERR_PUSH_ERROR(ret);
116 }
117 return ret;
118 }
119
120 static BSL_ASN1_TemplateItem g_signTempl[] = {
121 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
122 {BSL_ASN1_TAG_INTEGER, 0, 1},
123 {BSL_ASN1_TAG_INTEGER, 0, 1},
124 };
125
CheckSignBnParams(const BN_BigNum * r,const BN_BigNum * s,uint8_t * encode,uint32_t * encodeLen)126 static int32_t CheckSignBnParams(const BN_BigNum *r, const BN_BigNum *s, uint8_t *encode, uint32_t *encodeLen)
127 {
128 if (r == NULL || s == NULL || encode == NULL || encodeLen == NULL) {
129 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
130 return CRYPT_NULL_INPUT;
131 }
132
133 // The big number must be non-negative.
134 if (BN_IsNegative(r) || BN_IsNegative(s)) {
135 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
136 return CRYPT_INVALID_ARG;
137 }
138
139 // The big number must be non-zero.
140 if (BN_IsZero(r) || BN_IsZero(s)) {
141 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
142 return CRYPT_INVALID_ARG;
143 }
144
145 return CRYPT_SUCCESS;
146 }
147
ConvertBNToBuffer(const BN_BigNum * bn,uint8_t ** outBuf,uint32_t * outLen)148 static int32_t ConvertBNToBuffer(const BN_BigNum *bn, uint8_t **outBuf, uint32_t *outLen)
149 {
150 uint32_t len = BN_Bytes(bn);
151 uint8_t *buf = (uint8_t *)BSL_SAL_Malloc(len);
152 if (buf == NULL) {
153 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
154 return CRYPT_MEM_ALLOC_FAIL;
155 }
156
157 int32_t ret = BN_Bn2Bin(bn, buf, &len);
158 if (ret != CRYPT_SUCCESS) {
159 BSL_SAL_Free(buf);
160 BSL_ERR_PUSH_ERROR(ret);
161 return ret;
162 }
163
164 *outBuf = buf;
165 *outLen = len;
166 return CRYPT_SUCCESS;
167 }
168
CRYPT_EAL_EncodeSign(const BN_BigNum * r,const BN_BigNum * s,uint8_t * encode,uint32_t * encodeLen)169 int32_t CRYPT_EAL_EncodeSign(const BN_BigNum *r, const BN_BigNum *s, uint8_t *encode, uint32_t *encodeLen)
170 {
171 int32_t ret = CheckSignBnParams(r, s, encode, encodeLen);
172 if (ret != CRYPT_SUCCESS) {
173 return ret;
174 }
175
176 uint8_t *rBuf = NULL;
177 uint8_t *sBuf = NULL;
178 uint32_t rLen = 0;
179 uint32_t sLen = 0;
180
181 // Prepare the buffer for r.
182 ret = ConvertBNToBuffer(r, &rBuf, &rLen);
183 if (ret != CRYPT_SUCCESS) {
184 return ret; // no need to push err
185 }
186
187 // Prepare the buffer for s.
188 ret = ConvertBNToBuffer(s, &sBuf, &sLen);
189 if (ret != CRYPT_SUCCESS) {
190 BSL_SAL_Free(rBuf);
191 return ret; // no need to push err
192 }
193
194 BSL_ASN1_Buffer asnArr[2] = {
195 {BSL_ASN1_TAG_INTEGER, rLen, rBuf},
196 {BSL_ASN1_TAG_INTEGER, sLen, sBuf}
197 };
198 BSL_ASN1_Template templ = {g_signTempl, sizeof(g_signTempl) / sizeof(g_signTempl[0])};
199 ret = EncodeAsn1Template(&templ, asnArr, 2, encode, encodeLen);
200
201 BSL_SAL_Free(rBuf);
202 BSL_SAL_Free(sBuf);
203
204 return ret;
205 }
206
CRYPT_EAL_DecodeSign(const uint8_t * encode,uint32_t encodeLen,BN_BigNum * r,BN_BigNum * s)207 int32_t CRYPT_EAL_DecodeSign(const uint8_t *encode, uint32_t encodeLen, BN_BigNum *r, BN_BigNum *s)
208 {
209 if (encode == NULL || encodeLen == 0 || r == NULL || s == NULL) {
210 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
211 return CRYPT_NULL_INPUT;
212 }
213
214 // Decode ASN.1 sequence to get r and s components
215 BSL_ASN1_Buffer asnArr[2] = {0}; // 2: r and s
216 BSL_ASN1_Template templ = {g_signTempl, sizeof(g_signTempl) / sizeof(g_signTempl[0])};
217 int32_t ret = DecodeAsn1Template(encode, encodeLen, &templ, asnArr, 2); // 2: r and s
218 if (ret != CRYPT_SUCCESS) {
219 BSL_ERR_PUSH_ERROR(ret);
220 return ret;
221 }
222
223 // Convert decoded buffers to big numbers
224 ret = BN_Bin2Bn(r, asnArr[0].buff, asnArr[0].len);
225 if (ret != CRYPT_SUCCESS) {
226 BSL_ERR_PUSH_ERROR(ret);
227 return ret;
228 }
229
230 ret = BN_Bin2Bn(s, asnArr[1].buff, asnArr[1].len);
231 if (ret != CRYPT_SUCCESS) {
232 BSL_ERR_PUSH_ERROR(ret);
233 }
234
235 return ret;
236 }
237 #endif
238
239 #ifdef HITLS_CRYPTO_SM2_CRYPT
CRYPT_EAL_GetSm2EncryptDataEncodeLen(uint32_t xLen,uint32_t yLen,uint32_t hashLen,uint32_t dataLen,uint32_t * maxLen)240 int32_t CRYPT_EAL_GetSm2EncryptDataEncodeLen(uint32_t xLen, uint32_t yLen, uint32_t hashLen, uint32_t dataLen,
241 uint32_t *maxLen)
242 {
243 if (maxLen == NULL || xLen > UINT32_MAX - 1 || yLen > UINT32_MAX - 1) {
244 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
245 return CRYPT_INVALID_ARG;
246 }
247 uint32_t xEncodeLen = 0;
248 uint32_t yEncodeLen = 0;
249 uint32_t hashEncodeLen = 0;
250 uint32_t cipherEncodeLen = 0;
251
252 int32_t ret = BSL_ASN1_GetEncodeLen(xLen + 1, &xEncodeLen); // + 1: if high bit is 1, should add a leading 0x00
253 if (ret != CRYPT_SUCCESS) {
254 BSL_ERR_PUSH_ERROR(ret);
255 return ret;
256 }
257
258 ret = BSL_ASN1_GetEncodeLen(yLen + 1, &yEncodeLen); // + 1: if high bit is 1, should add a leading 0x00
259 if (ret != CRYPT_SUCCESS) {
260 BSL_ERR_PUSH_ERROR(ret);
261 return ret;
262 }
263
264 ret = BSL_ASN1_GetEncodeLen(hashLen, &hashEncodeLen);
265 if (ret != CRYPT_SUCCESS) {
266 BSL_ERR_PUSH_ERROR(ret);
267 return ret;
268 }
269
270 ret = BSL_ASN1_GetEncodeLen(dataLen, &cipherEncodeLen);
271 if (ret != CRYPT_SUCCESS) {
272 BSL_ERR_PUSH_ERROR(ret);
273 return ret;
274 }
275
276 if (xEncodeLen > UINT32_MAX - yEncodeLen ||
277 (xEncodeLen + yEncodeLen) > UINT32_MAX - hashEncodeLen ||
278 (xEncodeLen + yEncodeLen + hashEncodeLen) > UINT32_MAX - cipherEncodeLen) {
279 BSL_ERR_PUSH_ERROR(CRYPT_ENCODE_ERR_SM2_ENCRYPT_DATA_LEN_OVERFLOW);
280 return CRYPT_ENCODE_ERR_SM2_ENCRYPT_DATA_LEN_OVERFLOW;
281 }
282
283 // Calculate the total length of the encoded data
284 ret = BSL_ASN1_GetEncodeLen(xEncodeLen + yEncodeLen + hashEncodeLen + cipherEncodeLen, maxLen);
285 if (ret != CRYPT_SUCCESS) {
286 BSL_ERR_PUSH_ERROR(ret);
287 }
288 return ret;
289 }
290
291 /**
292 * Reference: GM/T 0009-2012 7.2
293 * Define template for SM2 encryption data structure:
294 * SM2Cipher ::= SEQUENCE {
295 * XCoordinate INTEGER,
296 * YCoordinate INTEGER,
297 * HASH OCTET STRING SIZE(32),
298 * CipherText OCTET STRING
299 * }
300 */
301 static BSL_ASN1_TemplateItem g_sm2EncryptTempl[] = {
302 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
303 {BSL_ASN1_TAG_INTEGER, 0, 1}, // x coordinate
304 {BSL_ASN1_TAG_INTEGER, 0, 1}, // y coordinate
305 {BSL_ASN1_TAG_OCTETSTRING, 0, 1}, // hash (c3)
306 {BSL_ASN1_TAG_OCTETSTRING, 0, 1} // ciphertext (c2)
307 };
308 #define SM2_ENCRYPT_DATA_ITEM_NUM 4
309
CheckSm2EncryptData(const CRYPT_SM2_EncryptData * data)310 int32_t CheckSm2EncryptData(const CRYPT_SM2_EncryptData *data)
311 {
312 if (data == NULL) {
313 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
314 return CRYPT_NULL_INPUT;
315 }
316
317 // Check x and y coordinate
318 if (data->x == NULL || data->xLen == 0 || data->y == NULL || data->yLen == 0) {
319 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
320 return CRYPT_INVALID_ARG;
321 }
322
323 // Check hash
324 if (data->hash == NULL || data->hashLen == 0) {
325 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
326 return CRYPT_INVALID_ARG;
327 }
328
329 // Check cipher
330 if (data->cipher == NULL || data->cipherLen == 0) {
331 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
332 return CRYPT_INVALID_ARG;
333 }
334
335 return CRYPT_SUCCESS;
336 }
337
CRYPT_EAL_EncodeSm2EncryptData(const CRYPT_SM2_EncryptData * data,uint8_t * encode,uint32_t * encodeLen)338 int32_t CRYPT_EAL_EncodeSm2EncryptData(const CRYPT_SM2_EncryptData *data, uint8_t *encode, uint32_t *encodeLen)
339 {
340 int32_t ret = CheckSm2EncryptData(data);
341 if (ret != CRYPT_SUCCESS) {
342 BSL_ERR_PUSH_ERROR(ret);
343 return ret;
344 }
345 if (encode == NULL || encodeLen == NULL) {
346 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
347 return CRYPT_NULL_INPUT;
348 }
349
350 BSL_ASN1_Buffer asnArr[SM2_ENCRYPT_DATA_ITEM_NUM] = {
351 {BSL_ASN1_TAG_INTEGER, data->xLen, data->x}, // x coordinate
352 {BSL_ASN1_TAG_INTEGER, data->yLen, data->y}, // y coordinate
353 {BSL_ASN1_TAG_OCTETSTRING, data->hashLen, data->hash}, // hash
354 {BSL_ASN1_TAG_OCTETSTRING, data->cipherLen, data->cipher} // ciphertext
355 };
356 BSL_ASN1_Template templ = {g_sm2EncryptTempl, sizeof(g_sm2EncryptTempl) / sizeof(g_sm2EncryptTempl[0])};
357
358 return EncodeAsn1Template(&templ, asnArr, SM2_ENCRYPT_DATA_ITEM_NUM, encode, encodeLen);
359 }
360
CRYPT_EAL_DecodeSm2EncryptData(const uint8_t * encode,uint32_t encodeLen,CRYPT_SM2_EncryptData * data)361 int32_t CRYPT_EAL_DecodeSm2EncryptData(const uint8_t *encode, uint32_t encodeLen, CRYPT_SM2_EncryptData *data)
362 {
363 int32_t ret = CheckSm2EncryptData(data);
364 if (ret != CRYPT_SUCCESS) {
365 BSL_ERR_PUSH_ERROR(ret);
366 return ret;
367 }
368 if (encode == NULL || encodeLen == 0) {
369 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
370 return CRYPT_NULL_INPUT;
371 }
372
373 BSL_ASN1_Buffer asnArr[SM2_ENCRYPT_DATA_ITEM_NUM] = {0};
374 BSL_ASN1_Template templ = {g_sm2EncryptTempl, sizeof(g_sm2EncryptTempl) / sizeof(g_sm2EncryptTempl[0])};
375 ret = DecodeAsn1Template(encode, encodeLen, &templ, asnArr, SM2_ENCRYPT_DATA_ITEM_NUM);
376 if (ret != CRYPT_SUCCESS) {
377 BSL_ERR_PUSH_ERROR(ret);
378 return ret;
379 }
380
381 // Validate lengths
382 if (asnArr[0].len > data->xLen || asnArr[1].len > data->yLen ||
383 asnArr[2].len > data->hashLen || // 2: hash
384 asnArr[3].len > data->cipherLen) { // 3: cipher
385 BSL_ERR_PUSH_ERROR(CRYPT_DECODE_BUFF_NOT_ENOUGH);
386 return CRYPT_DECODE_BUFF_NOT_ENOUGH;
387 }
388 // 1: point xy
389 (void)memcpy_s(data->x + (data->xLen - asnArr[0].len), asnArr[0].len, asnArr[0].buff, asnArr[0].len);
390 (void)memcpy_s(data->y + (data->yLen - asnArr[1].len), asnArr[1].len, asnArr[1].buff, asnArr[1].len);
391 (void)memcpy_s(data->hash, data->hashLen, asnArr[2].buff, asnArr[2].len); // 2: hash
392 (void)memcpy_s(data->cipher, data->cipherLen, asnArr[3].buff, asnArr[3].len); // 3: cipher
393 data->hashLen = asnArr[2].len; // 2: hash
394 data->cipherLen = asnArr[3].len; // 3: cipher
395
396 return CRYPT_SUCCESS;
397 }
398 #endif // HITLS_CRYPTO_SM2_CRYPT
399
400 #endif
401