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
12 #include <stdio.h>
13 #include <gmssl/sm3.h>
14 #include <gmssl/oid.h>
15 #include <gmssl/digest.h>
16 #include <gmssl/error.h>
17
18
19 typedef struct {
20 int oid;
21 char *short_name;
22 char *display_name;
23 } DIGEST_TABLE;
24
25 DIGEST_TABLE digest_table[] = {
26 { OID_sm3, "sm3", "SM3" },
27 // { OID_md5, "md5", "MD5" },
28 { OID_sha1, "sha1", "SHA-1" },
29 { OID_sha224, "sha224", "SHA-224" },
30 { OID_sha256, "sha256", "SHA-256" },
31 { OID_sha384, "sha384", "SHA-384" },
32 { OID_sha512, "sha512", "SHA-512" },
33 };
34
digest_name(const DIGEST * digest)35 const char *digest_name(const DIGEST *digest)
36 {
37 int i;
38 for (i = 0; i < sizeof(digest_table)/sizeof(digest_table[0]); i++) {
39 if (digest->oid == digest_table[i].oid) {
40 return digest_table[i].short_name;
41 }
42 }
43 return NULL;
44 }
45
digest_init(DIGEST_CTX * ctx,const DIGEST * algor)46 int digest_init(DIGEST_CTX *ctx, const DIGEST *algor)
47 {
48 memset(ctx, 0, sizeof(DIGEST_CTX));
49 if (algor == NULL) {
50 error_print();
51 return -1;
52 }
53 ctx->digest = algor;
54 ctx->digest->init(ctx);
55 return 1;
56 }
57
digest_update(DIGEST_CTX * ctx,const uint8_t * data,size_t datalen)58 int digest_update(DIGEST_CTX *ctx, const uint8_t *data, size_t datalen)
59 {
60 if (data == NULL || datalen == 0) {
61 return 0;
62 }
63 ctx->digest->update(ctx, data, datalen);
64 return 1;
65 }
66
digest_finish(DIGEST_CTX * ctx,uint8_t * dgst,size_t * dgstlen)67 int digest_finish(DIGEST_CTX *ctx, uint8_t *dgst, size_t *dgstlen)
68 {
69 if (dgst == NULL || dgstlen == NULL) {
70 error_print();
71 return -1;
72 }
73 ctx->digest->finish(ctx, dgst);
74 *dgstlen = ctx->digest->digest_size;
75 return 1;
76 }
77
digest(const DIGEST * digest,const uint8_t * data,size_t datalen,uint8_t * dgst,size_t * dgstlen)78 int digest(const DIGEST *digest, const uint8_t *data, size_t datalen,
79 uint8_t *dgst, size_t *dgstlen)
80 {
81 DIGEST_CTX ctx;
82 if (digest_init(&ctx, digest) != 1
83 || digest_update(&ctx, data, datalen) < 0
84 || digest_finish(&ctx, dgst, dgstlen) != 1) {
85 error_print();
86 return -1;
87 }
88 memset(&ctx, 0, sizeof(DIGEST_CTX));
89 return 1;
90 }
91
digest_from_name(const char * name)92 const DIGEST *digest_from_name(const char *name)
93 {
94 if (!strcmp(name, "sm3") || !strcmp(name, "SM3")) {
95 return DIGEST_sm3();
96 /*
97 } else if (!strcmp(name, "md5") || !strcmp(name, "MD5")) {
98 return DIGEST_md5();
99 */
100 } else if (!strcmp(name, "sha1") || !strcmp(name, "SHA1")) {
101 return DIGEST_sha1();
102 } else if (!strcmp(name, "sha224") || !strcmp(name, "SHA224")) {
103 return DIGEST_sha224();
104 } else if (!strcmp(name, "sha256") || !strcmp(name, "SHA256")) {
105 return DIGEST_sha256();
106 } else if (!strcmp(name, "sha384") || !strcmp(name, "SHA384")) {
107 return DIGEST_sha384();
108 } else if (!strcmp(name, "sha512") || !strcmp(name, "SHA512")) {
109 return DIGEST_sha512();
110 } else if (!strcmp(name, "sha512-224") || !strcmp(name, "SHA512-224")) {
111 return DIGEST_sha512_224();
112 } else if (!strcmp(name, "sha512-256") || !strcmp(name, "SHA512-256")) {
113 return DIGEST_sha512_256();
114 }
115 return NULL;
116 }
117
sm3_digest_init(DIGEST_CTX * ctx)118 static int sm3_digest_init(DIGEST_CTX *ctx)
119 {
120 if (!ctx) {
121 error_print();
122 return -1;
123 }
124 sm3_init(&ctx->u.sm3_ctx);
125 return 1;
126 }
127
sm3_digest_update(DIGEST_CTX * ctx,const uint8_t * in,size_t inlen)128 static int sm3_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
129 {
130 if (!ctx || (!in && inlen != 0)) {
131 error_print();
132 return -1;
133 }
134 sm3_update(&ctx->u.sm3_ctx, in, inlen);
135 return 1;
136 }
137
sm3_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)138 static int sm3_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
139 {
140 if (!ctx || !dgst) {
141 error_print();
142 return -1;
143 }
144 sm3_finish(&ctx->u.sm3_ctx, dgst);
145 return 1;
146 }
147
148 static const DIGEST sm3_digest_object = {
149 OID_sm3,
150 SM3_DIGEST_SIZE,
151 SM3_BLOCK_SIZE,
152 sizeof(SM3_CTX),
153 sm3_digest_init,
154 sm3_digest_update,
155 sm3_digest_finish,
156 };
157
DIGEST_sm3(void)158 const DIGEST *DIGEST_sm3(void)
159 {
160 return &sm3_digest_object;
161 }
162
163 /*
164 #include <gmssl/md5.h>
165
166 static int md5_digest_init(DIGEST_CTX *ctx)
167 {
168 if (!ctx) {
169 error_print();
170 return -1;
171 }
172 md5_init(&ctx->u.md5_ctx);
173 return 1;
174 }
175
176 static int md5_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
177 {
178 if (!ctx || (!in && inlen != 0)) {
179 error_print();
180 return -1;
181 }
182 md5_update(&ctx->u.md5_ctx, in, inlen);
183 return 1;
184 }
185
186 static int md5_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
187 {
188 if (!ctx || !dgst) {
189 error_print();
190 return -1;
191 }
192 md5_finish(&ctx->u.md5_ctx, dgst);
193 return 1;
194 }
195
196 static const DIGEST md5_digest_object = {
197 OID_md5,
198 MD5_DIGEST_SIZE,
199 MD5_BLOCK_SIZE,
200 sizeof(MD5_CTX),
201 md5_digest_init,
202 md5_digest_update,
203 md5_digest_finish,
204 };
205
206 const DIGEST *DIGEST_md5(void)
207 {
208 return &md5_digest_object;
209 }
210 */
211
212
213 #include <gmssl/sha1.h>
214
sha1_digest_init(DIGEST_CTX * ctx)215 static int sha1_digest_init(DIGEST_CTX *ctx)
216 {
217 if (!ctx) {
218 error_print();
219 return -1;
220 }
221 sha1_init(&ctx->u.sha1_ctx);
222 return 1;
223 }
224
sha1_digest_update(DIGEST_CTX * ctx,const uint8_t * in,size_t inlen)225 static int sha1_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
226 {
227 if (!ctx || (!in && inlen != 0)) {
228 error_print();
229 return -1;
230 }
231 sha1_update(&ctx->u.sha1_ctx, in, inlen);
232 return 1;
233 }
234
sha1_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)235 static int sha1_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
236 {
237 if (!ctx || !dgst) {
238 error_print();
239 return -1;
240 }
241 sha1_finish(&ctx->u.sha1_ctx, dgst);
242 return 1;
243 }
244
245 static const DIGEST sha1_digest_object = {
246 OID_sha1,
247 SHA1_DIGEST_SIZE,
248 SHA1_BLOCK_SIZE,
249 sizeof(SHA1_CTX),
250 sha1_digest_init,
251 sha1_digest_update,
252 sha1_digest_finish,
253 };
254
DIGEST_sha1(void)255 const DIGEST *DIGEST_sha1(void)
256 {
257 return &sha1_digest_object;
258 }
259
260 #include <gmssl/sha2.h>
261
sha224_digest_init(DIGEST_CTX * ctx)262 static int sha224_digest_init(DIGEST_CTX *ctx)
263 {
264 if (!ctx) {
265 error_print();
266 return -1;
267 }
268 sha224_init(&ctx->u.sha224_ctx);
269 return 1;
270 }
271
sha224_digest_update(DIGEST_CTX * ctx,const uint8_t * in,size_t inlen)272 static int sha224_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
273 {
274 if (!ctx || (!in && inlen != 0)) {
275 error_print();
276 return -1;
277 }
278 sha224_update(&ctx->u.sha224_ctx, in, inlen);
279 return 1;
280 }
281
sha224_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)282 static int sha224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
283 {
284 if (!ctx || !dgst) {
285 error_print();
286 return -1;
287 }
288 sha224_finish(&ctx->u.sha224_ctx, dgst);
289 return 1;
290 }
291
292 static const DIGEST sha224_digest_object = {
293 OID_sha224,
294 SHA224_DIGEST_SIZE,
295 SHA224_BLOCK_SIZE,
296 sizeof(SHA224_CTX),
297 sha224_digest_init,
298 sha224_digest_update,
299 sha224_digest_finish,
300 };
301
DIGEST_sha224(void)302 const DIGEST *DIGEST_sha224(void)
303 {
304 return &sha224_digest_object;
305 }
306
sha256_digest_init(DIGEST_CTX * ctx)307 static int sha256_digest_init(DIGEST_CTX *ctx)
308 {
309 if (!ctx) {
310 error_print();
311 return -1;
312 }
313 sha256_init(&ctx->u.sha256_ctx);
314 return 1;
315 }
316
sha256_digest_update(DIGEST_CTX * ctx,const uint8_t * in,size_t inlen)317 static int sha256_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
318 {
319 if (!ctx || (!in && inlen != 0)) {
320 error_print();
321 return -1;
322 }
323 sha256_update(&ctx->u.sha256_ctx, in, inlen);
324 return 1;
325 }
326
sha256_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)327 static int sha256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
328 {
329 if (!ctx || !dgst) {
330 error_print();
331 return -1;
332 }
333 sha256_finish(&ctx->u.sha256_ctx, dgst);
334 return 1;
335 }
336
337 static const DIGEST sha256_digest_object = {
338 OID_sha256,
339 SHA256_DIGEST_SIZE,
340 SHA256_BLOCK_SIZE,
341 sizeof(SHA256_CTX),
342 sha256_digest_init,
343 sha256_digest_update,
344 sha256_digest_finish,
345 };
346
DIGEST_sha256(void)347 const DIGEST *DIGEST_sha256(void)
348 {
349 return &sha256_digest_object;
350 }
351
352
sha384_digest_init(DIGEST_CTX * ctx)353 static int sha384_digest_init(DIGEST_CTX *ctx)
354 {
355 if (!ctx) {
356 error_print();
357 return -1;
358 }
359 sha384_init(&ctx->u.sha384_ctx);
360 return 1;
361 }
362
sha384_digest_update(DIGEST_CTX * ctx,const uint8_t * in,size_t inlen)363 static int sha384_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
364 {
365 if (!ctx || (!in && inlen != 0)) {
366 error_print();
367 return -1;
368 }
369 sha384_update(&ctx->u.sha384_ctx, in, inlen);
370 return 1;
371 }
372
sha384_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)373 static int sha384_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
374 {
375 if (!ctx || !dgst) {
376 error_print();
377 return -1;
378 }
379 sha384_finish(&ctx->u.sha384_ctx, dgst);
380 return 1;
381 }
382
383 static const DIGEST sha384_digest_object = {
384 OID_sha384,
385 SHA384_DIGEST_SIZE,
386 SHA384_BLOCK_SIZE,
387 sizeof(SHA384_CTX),
388 sha384_digest_init,
389 sha384_digest_update,
390 sha384_digest_finish,
391 };
392
DIGEST_sha384(void)393 const DIGEST *DIGEST_sha384(void)
394 {
395 return &sha384_digest_object;
396 }
397
398
sha512_digest_init(DIGEST_CTX * ctx)399 static int sha512_digest_init(DIGEST_CTX *ctx)
400 {
401 if (!ctx) {
402 error_print();
403 return -1;
404 }
405 sha512_init(&ctx->u.sha512_ctx);
406 return 1;
407 }
408
sha512_digest_update(DIGEST_CTX * ctx,const uint8_t * in,size_t inlen)409 static int sha512_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen)
410 {
411 if (!ctx || (!in && inlen != 0)) {
412 error_print();
413 return -1;
414 }
415 sha512_update(&ctx->u.sha512_ctx, in, inlen);
416 return 1;
417 }
418
sha512_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)419 static int sha512_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
420 {
421 if (!ctx || !dgst) {
422 error_print();
423 return -1;
424 }
425 sha512_finish(&ctx->u.sha512_ctx, dgst);
426 return 1;
427 }
428
429 static const DIGEST sha512_digest_object = {
430 OID_sha512,
431 SHA512_DIGEST_SIZE,
432 SHA512_BLOCK_SIZE,
433 sizeof(SHA512_CTX),
434 sha512_digest_init,
435 sha512_digest_update,
436 sha512_digest_finish,
437 };
438
DIGEST_sha512(void)439 const DIGEST *DIGEST_sha512(void)
440 {
441 return &sha512_digest_object;
442 }
443
444
sha512_224_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)445 static int sha512_224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
446 {
447 uint8_t buf[SHA512_DIGEST_SIZE];
448 if (!ctx || !dgst) {
449 error_print();
450 return -1;
451 }
452 sha512_finish(&ctx->u.sha512_ctx, buf);
453 memcpy(dgst, buf, SHA224_DIGEST_SIZE);
454 memset(buf, 0, sizeof(buf));
455 return 1;
456 }
457
458 static const DIGEST sha512_224_digest_object = {
459 OID_sha512_224,
460 SHA224_DIGEST_SIZE,
461 SHA512_BLOCK_SIZE,
462 sizeof(SHA512_CTX),
463 sha512_digest_init,
464 sha512_digest_update,
465 sha512_224_digest_finish,
466 };
467
DIGEST_sha512_224(void)468 const DIGEST *DIGEST_sha512_224(void)
469 {
470 return &sha512_224_digest_object;
471 }
472
473
sha512_256_digest_finish(DIGEST_CTX * ctx,uint8_t * dgst)474 static int sha512_256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst)
475 {
476 uint8_t buf[SHA512_DIGEST_SIZE];
477 if (!ctx || !dgst) {
478 error_print();
479 return -1;
480 }
481 sha512_finish(&ctx->u.sha512_ctx, buf);
482 memcpy(dgst, buf, SHA256_DIGEST_SIZE);
483 memset(buf, 0, sizeof(buf));
484 return 1;
485 }
486
487
488 static const DIGEST sha512_256_digest_object = {
489 OID_sha512_256,
490 SHA256_DIGEST_SIZE,
491 SHA512_BLOCK_SIZE,
492 sizeof(SHA512_CTX),
493 sha512_digest_init,
494 sha512_digest_update,
495 sha512_256_digest_finish,
496 };
497
DIGEST_sha512_256(void)498 const DIGEST *DIGEST_sha512_256(void)
499 {
500 return &sha512_256_digest_object;
501 }
502