1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <gmssl/sm2.h>
15 #include <gmssl/pem.h>
16 #include <gmssl/oid.h>
17 #include <gmssl/asn1.h>
18 #include <gmssl/error.h>
19 #include <gmssl/pbkdf2.h>
20 #include <gmssl/digest.h>
21 #include <gmssl/sm4.h>
22 #include <gmssl/rand.h>
23 #include <gmssl/x509_alg.h>
24
25
26 static const uint32_t oid_hmac_sm3[] = { oid_sm_algors,401,2 };
27 static const size_t oid_hmac_sm3_cnt = sizeof(oid_hmac_sm3)/sizeof(oid_hmac_sm3[0]);
28
pbkdf2_prf_name(int oid)29 char *pbkdf2_prf_name(int oid)
30 {
31 switch (oid) {
32 case OID_hmac_sm3: return "hmac-sm3";
33 }
34 return NULL;
35 }
36
pbkdf2_prf_from_name(const char * name)37 int pbkdf2_prf_from_name(const char *name)
38 {
39 if (strcmp(name, "hmac-sm3") == 0) {
40 return OID_hmac_sm3;
41 }
42 return 0;
43 }
44
pbkdf2_prf_to_der(int oid,uint8_t ** out,size_t * outlen)45 int pbkdf2_prf_to_der(int oid, uint8_t **out, size_t *outlen)
46 {
47 size_t len = 0;
48 if (oid == -1)
49 return 0;
50
51 if (oid != OID_hmac_sm3) {
52 error_print();
53 return -1;
54 }
55 if (asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, NULL, &len) != 1
56 || asn1_sequence_header_to_der(len, out, outlen) != 1
57 || asn1_object_identifier_to_der(oid_hmac_sm3, oid_hmac_sm3_cnt, out, outlen) != 1) {
58 error_print();
59 return -1;
60 }
61 return 1;
62 }
63
pbkdf2_prf_from_der(int * oid,const uint8_t ** in,size_t * inlen)64 int pbkdf2_prf_from_der(int *oid, const uint8_t **in, size_t *inlen)
65 {
66 int ret;
67 const uint8_t *d;
68 size_t dlen;
69 uint32_t nodes[32];
70 size_t nodes_cnt;
71
72 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
73 if (ret < 0) error_print();
74 else *oid = -1;
75 return ret;
76 }
77 if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1
78 || asn1_object_identifier_equ(nodes, nodes_cnt, oid_hmac_sm3, oid_hmac_sm3_cnt) != 1
79 || asn1_length_is_zero(dlen) != 1) {
80 error_print();
81 return -1;
82 }
83 *oid = OID_hmac_sm3;
84 return 1;
85 }
86
pbkdf2_params_to_der(const uint8_t * salt,size_t saltlen,int iter,int keylen,int prf,uint8_t ** out,size_t * outlen)87 int pbkdf2_params_to_der(
88 const uint8_t *salt, size_t saltlen,
89 int iter,
90 int keylen,
91 int prf,
92 uint8_t **out, size_t *outlen)
93 {
94 size_t len = 0;
95 if (asn1_octet_string_to_der(salt, saltlen, NULL, &len) != 1
96 || asn1_int_to_der(iter, NULL, &len) != 1
97 || asn1_int_to_der(keylen, NULL, &len) < 0
98 || pbkdf2_prf_to_der(prf, NULL, &len) < 0
99 || asn1_sequence_header_to_der(len, out, outlen) != 1
100 || asn1_octet_string_to_der(salt, saltlen, out, outlen) != 1
101 || asn1_int_to_der(iter, out, outlen) != 1
102 || asn1_int_to_der(keylen, out, outlen) < 0
103 || pbkdf2_prf_to_der(prf, out, outlen) < 0) {
104 error_print();
105 return -1;
106 }
107 return 1;
108 }
109
pbkdf2_params_from_der(const uint8_t ** salt,size_t * saltlen,int * iter,int * keylen,int * prf,const uint8_t ** in,size_t * inlen)110 int pbkdf2_params_from_der(
111 const uint8_t **salt, size_t *saltlen,
112 int *iter,
113 int *keylen,
114 int *prf,
115 const uint8_t **in, size_t *inlen)
116 {
117 int ret;
118 const uint8_t *d;
119 size_t dlen;
120
121 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
122 if (ret < 0) error_print();
123 return ret;
124 }
125 if (asn1_octet_string_from_der(salt, saltlen, &d, &dlen) != 1
126 || asn1_int_from_der(iter, &d, &dlen) != 1
127 || asn1_int_from_der(keylen, &d, &dlen) < 0
128 || pbkdf2_prf_from_der(prf, &d, &dlen) < 0
129 || asn1_check(*saltlen > 0) != 1
130 || asn1_check(*iter > 0) != 1
131 || asn1_length_is_zero(dlen) != 1) {
132 error_print();
133 return -1;
134 }
135 return 1;
136 }
137
pbkdf2_params_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)138 int pbkdf2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
139 {
140 int ret;
141 const uint8_t *p;
142 size_t len;
143 int val;
144
145 format_print(fp, fmt, ind, "%s\n", label);
146 ind += 4;
147
148 if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
149 format_bytes(fp, fmt, ind, "salt", p, len);
150 if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err;
151 format_print(fp, fmt, ind, "iterationCount: %d\n", val);
152 if ((ret = asn1_int_from_der(&val, &d, &dlen)) < 0) goto err;
153 if (ret) format_print(fp, fmt, ind, "keyLength: %d\n", val);
154 if ((ret = pbkdf2_prf_from_der(&val, &d, &dlen)) < 0) goto err;
155 if (ret) format_print(fp, fmt, ind, "prf: %s\n", pbkdf2_prf_name(val));
156 if (asn1_length_is_zero(dlen) != 1) goto err;
157 return 1;
158 err:
159 error_print();
160 return -1;
161 }
162
163 static const uint32_t oid_pbkdf2[] = { oid_pkcs5,12 };
164 static const size_t oid_pbkdf2_cnt = sizeof(oid_pbkdf2)/sizeof(oid_pbkdf2[0]);
165
pbkdf2_algor_to_der(const uint8_t * salt,size_t saltlen,int iter,int keylen,int prf,uint8_t ** out,size_t * outlen)166 int pbkdf2_algor_to_der(
167 const uint8_t *salt, size_t saltlen,
168 int iter,
169 int keylen,
170 int prf,
171 uint8_t **out, size_t *outlen)
172 {
173 size_t len = 0;
174 if (asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, NULL, &len) != 1
175 || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1
176 || asn1_sequence_header_to_der(len, out, outlen) != 1
177 || asn1_object_identifier_to_der(oid_pbkdf2, oid_pbkdf2_cnt, out, outlen) != 1
178 || pbkdf2_params_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1) {
179 error_print();
180 return -1;
181 }
182 return 1;
183 }
184
pbkdf2_algor_from_der(const uint8_t ** salt,size_t * saltlen,int * iter,int * keylen,int * prf,const uint8_t ** in,size_t * inlen)185 int pbkdf2_algor_from_der(
186 const uint8_t **salt, size_t *saltlen,
187 int *iter,
188 int *keylen,
189 int *prf,
190 const uint8_t **in, size_t *inlen)
191 {
192 int ret;
193 const uint8_t *d;
194 size_t dlen;
195 uint32_t nodes[32];
196 size_t nodes_cnt;
197
198 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
199 if (ret < 0) error_print();
200 return ret;
201 }
202 if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1
203 || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1
204 || pbkdf2_params_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1
205 || asn1_length_is_zero(dlen) != 1) {
206 error_print();
207 return -1;
208 }
209 return 1;
210 }
211
pbkdf2_algor_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)212 int pbkdf2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
213 {
214 uint32_t nodes[32];
215 size_t nodes_cnt;
216 const uint8_t *p;
217 size_t len;
218
219 format_print(fp, fmt, ind, "%s\n", label);
220 ind += 4;
221
222 if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1
223 || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbkdf2, oid_pbkdf2_cnt) != 1) {
224 error_print();
225 return -1;
226 }
227 format_print(fp, fmt, ind, "algorithm: %s\n", "pbkdf2");
228 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
229 pbkdf2_params_print(fp, fmt, ind, "parameters", p, len);
230 if (asn1_length_is_zero(dlen) != 1) goto err;
231 return 1;
232 err:
233 error_print();
234 return -1;
235 }
236
pbes2_enc_algor_to_der(int oid,const uint8_t * iv,size_t ivlen,uint8_t ** out,size_t * outlen)237 int pbes2_enc_algor_to_der(int oid, const uint8_t *iv, size_t ivlen, uint8_t **out, size_t *outlen)
238 {
239 if (oid != OID_sm4_cbc) {
240 error_print();
241 return -1;
242 }
243 if (x509_encryption_algor_to_der(oid, iv, ivlen, out, outlen) != 1) {
244 error_print();
245 return -1;
246 }
247 return 1;
248 }
249
pbes2_enc_algor_from_der(int * oid,const uint8_t ** iv,size_t * ivlen,const uint8_t ** in,size_t * inlen)250 int pbes2_enc_algor_from_der(int *oid, const uint8_t **iv, size_t *ivlen, const uint8_t **in, size_t *inlen)
251 {
252 int ret;
253 if ((ret = x509_encryption_algor_from_der(oid, iv, ivlen, in, inlen)) != 1) {
254 if (ret < 0) error_print();
255 return ret;
256 }
257 if (*oid != OID_sm4_cbc) {
258 error_print();
259 return -1;
260 }
261 return 1;
262 }
263
pbes2_enc_algor_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)264 int pbes2_enc_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
265 {
266 return x509_encryption_algor_print(fp, fmt, ind, label, d, dlen);
267 }
268
pbes2_params_to_der(const uint8_t * salt,size_t saltlen,int iter,int keylen,int prf,int cipher,const uint8_t * iv,size_t ivlen,uint8_t ** out,size_t * outlen)269 int pbes2_params_to_der(
270 const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf,
271 int cipher, const uint8_t *iv, size_t ivlen,
272 uint8_t **out, size_t *outlen)
273 {
274 size_t len = 0;
275 if (pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, NULL, &len) != 1
276 || pbes2_enc_algor_to_der(cipher, iv, ivlen, NULL, &len) != 1
277 || asn1_sequence_header_to_der(len, out, outlen) != 1
278 || pbkdf2_algor_to_der(salt, saltlen, iter, keylen, prf, out, outlen) != 1
279 || pbes2_enc_algor_to_der(cipher, iv, ivlen, out, outlen) != 1) {
280 error_print();
281 return -1;
282 }
283 return 1;
284 }
285
pbes2_params_from_der(const uint8_t ** salt,size_t * saltlen,int * iter,int * keylen,int * prf,int * cipher,const uint8_t ** iv,size_t * ivlen,const uint8_t ** in,size_t * inlen)286 int pbes2_params_from_der(
287 const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf,
288 int *cipher, const uint8_t **iv, size_t *ivlen,
289 const uint8_t **in, size_t *inlen)
290 {
291 int ret;
292 const uint8_t *d;
293 size_t dlen;
294
295 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
296 if (ret < 0) error_print();
297 return ret;
298 }
299 if (pbkdf2_algor_from_der(salt, saltlen, iter, keylen, prf, &d, &dlen) != 1
300 || pbes2_enc_algor_from_der(cipher, iv, ivlen, &d, &dlen) != 1
301 || asn1_length_is_zero(dlen) != 1) {
302 error_print();
303 return -1;
304 }
305 return 1;
306 }
307
pbes2_params_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)308 int pbes2_params_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
309 {
310 const uint8_t *p;
311 size_t len;
312
313 format_print(fp, fmt, ind, "%s\n", label);
314 ind += 4;
315
316 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
317 pbkdf2_algor_print(fp, fmt, ind, "keyDerivationFunc", p, len);
318 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
319 pbes2_enc_algor_print(fp, fmt, ind, "encryptionScheme", p, len);
320 if (asn1_length_is_zero(dlen) != 1) goto err;
321 return 1;
322 err:
323 error_print();
324 return -1;
325 }
326
327
328 static const uint32_t oid_pbes2[] = { oid_pkcs5,13 };
329 static const size_t oid_pbes2_cnt = sizeof(oid_pbes2)/sizeof(oid_pbes2[0]);
330
pbes2_algor_to_der(const uint8_t * salt,size_t saltlen,int iter,int keylen,int prf,int cipher,const uint8_t * iv,size_t ivlen,uint8_t ** out,size_t * outlen)331 int pbes2_algor_to_der(
332 const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf,
333 int cipher, const uint8_t *iv, size_t ivlen,
334 uint8_t **out, size_t *outlen)
335 {
336 size_t len = 0;
337 if (asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, NULL, &len) != 1
338 || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1
339 || asn1_sequence_header_to_der(len, out, outlen) != 1
340 || asn1_object_identifier_to_der(oid_pbes2, oid_pbes2_cnt, out, outlen) != 1
341 || pbes2_params_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1) {
342 error_print();
343 return -1;
344 }
345 return 1;
346 }
347
pbes2_algor_from_der(const uint8_t ** salt,size_t * saltlen,int * iter,int * keylen,int * prf,int * cipher,const uint8_t ** iv,size_t * ivlen,const uint8_t ** in,size_t * inlen)348 int pbes2_algor_from_der(
349 const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf,
350 int *cipher, const uint8_t **iv, size_t *ivlen,
351 const uint8_t **in, size_t *inlen)
352 {
353 int ret;
354 const uint8_t *d;
355 size_t dlen;
356 int oid;
357 uint32_t nodes[32];
358 size_t nodes_cnt;
359
360 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
361 if (ret < 0) error_print();
362 return ret;
363 }
364 if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1
365 || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1
366 || pbes2_params_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1
367 || asn1_length_is_zero(dlen) != 1) {
368 error_print();
369 return -1;
370 }
371 return 1;
372 }
373
pbes2_algor_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)374 int pbes2_algor_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
375 {
376 uint32_t nodes[32];
377 size_t nodes_cnt;
378 const uint8_t *p;
379 size_t len;
380
381 format_print(fp, fmt, ind, "%s\n", label);
382 ind += 4;
383
384 if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &d, &dlen) != 1
385 || asn1_object_identifier_equ(nodes, nodes_cnt, oid_pbes2, oid_pbes2_cnt) != 1)
386 goto err;
387 format_print(fp, fmt, ind, "algorithm: %s\n", "pbes2");
388 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
389 pbes2_params_print(fp, fmt, ind, "parameters", p, len);
390 if (asn1_length_is_zero(dlen) != 1) goto err;
391 return 1;
392 err:
393 error_print();
394 return -1;
395 }
396
pkcs8_enced_private_key_info_to_der(const uint8_t * salt,size_t saltlen,int iter,int keylen,int prf,int cipher,const uint8_t * iv,size_t ivlen,const uint8_t * enced,size_t encedlen,uint8_t ** out,size_t * outlen)397 int pkcs8_enced_private_key_info_to_der(
398 const uint8_t *salt, size_t saltlen, int iter, int keylen, int prf,
399 int cipher, const uint8_t *iv, size_t ivlen,
400 const uint8_t *enced, size_t encedlen,
401 uint8_t **out, size_t *outlen)
402 {
403 size_t len = 0;
404 if (pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, NULL, &len) != 1
405 || asn1_octet_string_to_der(enced, encedlen, NULL, &len) != 1
406 || asn1_sequence_header_to_der(len, out, outlen) != 1
407 || pbes2_algor_to_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, out, outlen) != 1
408 || asn1_octet_string_to_der(enced, encedlen, out, outlen) != 1) {
409 error_print();
410 return -1;
411 }
412 return 1;
413 }
414
pkcs8_enced_private_key_info_from_der(const uint8_t ** salt,size_t * saltlen,int * iter,int * keylen,int * prf,int * cipher,const uint8_t ** iv,size_t * ivlen,const uint8_t ** enced,size_t * encedlen,const uint8_t ** in,size_t * inlen)415 int pkcs8_enced_private_key_info_from_der(
416 const uint8_t **salt, size_t *saltlen, int *iter, int *keylen, int *prf,
417 int *cipher, const uint8_t **iv, size_t *ivlen,
418 const uint8_t **enced, size_t *encedlen,
419 const uint8_t **in, size_t *inlen)
420 {
421 int ret;
422 const uint8_t *d;
423 size_t dlen;
424
425 if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
426 if (ret < 0) error_print();
427 return ret;
428 }
429 if (pbes2_algor_from_der(salt, saltlen, iter, keylen, prf, cipher, iv, ivlen, &d, &dlen) != 1
430 || asn1_octet_string_from_der(enced, encedlen, &d, &dlen) != 1
431 || asn1_length_is_zero(dlen) != 1) {
432 error_print();
433 return -1;
434 }
435 return 1;
436 }
437
pkcs8_enced_private_key_info_print(FILE * fp,int fmt,int ind,const char * label,const uint8_t * d,size_t dlen)438 int pkcs8_enced_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
439 {
440 const uint8_t *p;
441 size_t len;
442
443 format_print(fp, fmt, ind, "%s\n", label);
444 ind += 4;
445
446 if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
447 pbes2_algor_print(fp, fmt, ind, "encryptionAlgorithm", p, len);
448 if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
449 format_bytes(fp, fmt, ind, "encryptedData", p, len);
450 if (asn1_length_is_zero(dlen) != 1) goto err;
451 return 1;
452 err:
453 error_print();
454 return -1;
455 }
456