• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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