Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/libecc/src/examples/hash/hash.c
2066 views
1
/*
2
* Copyright (C) 2021 - This file is part of libecc project
3
*
4
* Authors:
5
* Ryad BENADJILA <[email protected]>
6
* Arnaud EBALARD <[email protected]>
7
*
8
* This software is licensed under a dual BSD and GPL v2 license.
9
* See LICENSE file at the root folder of the project.
10
*/
11
#include "hash.h"
12
13
/* Get a libecc hash type and mapping from a generic hash type */
14
ATTRIBUTE_WARN_UNUSED_RET static int get_libecc_hash(gen_hash_alg_type gen_hash_type, hash_alg_type *hash_type, const hash_mapping **hm, u8 *hlen, u8 *block_size)
15
{
16
int ret;
17
hash_alg_type htype = UNKNOWN_HASH_ALG;
18
19
MUST_HAVE((hash_type != NULL) && (hm != NULL), ret, err);
20
21
switch(gen_hash_type){
22
case HASH_SHA224:{
23
#ifdef WITH_HASH_SHA224
24
htype = SHA224;
25
#endif
26
break;
27
}
28
case HASH_SHA256:{
29
#ifdef WITH_HASH_SHA256
30
htype = SHA256;
31
#endif
32
break;
33
}
34
case HASH_SHA384:{
35
#ifdef WITH_HASH_SHA384
36
htype = SHA384;
37
#endif
38
break;
39
}
40
case HASH_SHA512:{
41
#ifdef WITH_HASH_SHA512
42
htype = SHA512;
43
#endif
44
break;
45
}
46
case HASH_SHA512_224:{
47
#ifdef WITH_HASH_SHA512_224
48
htype = SHA512_224;
49
#endif
50
break;
51
}
52
case HASH_SHA512_256:{
53
#ifdef WITH_HASH_SHA512_256
54
htype = SHA512_256;
55
#endif
56
break;
57
}
58
case HASH_SHA3_224:{
59
#ifdef WITH_HASH_SHA3_224
60
htype = SHA3_224;
61
#endif
62
break;
63
}
64
case HASH_SHA3_256:{
65
#ifdef WITH_HASH_SHA3_256
66
htype = SHA3_256;
67
#endif
68
break;
69
}
70
case HASH_SHA3_384:{
71
#ifdef WITH_HASH_SHA3_384
72
htype = SHA3_384;
73
#endif
74
break;
75
}
76
case HASH_SHA3_512:{
77
#ifdef WITH_HASH_SHA3_512
78
htype = SHA3_512;
79
#endif
80
break;
81
}
82
case HASH_SM3:{
83
#ifdef WITH_HASH_SM3
84
htype = SM3;
85
#endif
86
break;
87
}
88
case HASH_STREEBOG256:{
89
#ifdef WITH_HASH_STREEBOG256
90
htype = STREEBOG256;
91
#endif
92
break;
93
}
94
case HASH_STREEBOG512:{
95
#ifdef WITH_HASH_STREEBOG512
96
htype = STREEBOG512;
97
#endif
98
break;
99
}
100
case HASH_SHAKE256:{
101
#ifdef WITH_HASH_SHAKE256
102
htype = SHAKE256;
103
#endif
104
break;
105
}
106
case HASH_RIPEMD160:{
107
#ifdef WITH_HASH_RIPEMD160
108
htype = RIPEMD160;
109
#endif
110
break;
111
}
112
case HASH_BELT_HASH:{
113
#ifdef WITH_HASH_BELT_HASH
114
htype = BELT_HASH;
115
#endif
116
break;
117
}
118
case HASH_BASH224:{
119
#ifdef WITH_HASH_BASH224
120
htype = BASH224;
121
#endif
122
break;
123
}
124
case HASH_BASH256:{
125
#ifdef WITH_HASH_BASH256
126
htype = BASH256;
127
#endif
128
break;
129
}
130
case HASH_BASH384:{
131
#ifdef WITH_HASH_BASH384
132
htype = BASH384;
133
#endif
134
break;
135
}
136
case HASH_BASH512:{
137
#ifdef WITH_HASH_BASH512
138
htype = BASH512;
139
#endif
140
break;
141
}
142
143
default:{
144
htype = UNKNOWN_HASH_ALG;
145
break;
146
}
147
}
148
if(htype != UNKNOWN_HASH_ALG){
149
(*hash_type) = htype;
150
ret = get_hash_by_type(htype, hm); EG(ret, err);
151
ret = get_hash_sizes(htype, hlen, block_size); EG(ret, err);
152
MUST_HAVE(((*hlen) <= MAX_DIGEST_SIZE), ret, err);
153
ret = 0;
154
}
155
else{
156
ret = -1;
157
}
158
159
err:
160
if(ret && (hm != NULL)){
161
(*hm) = NULL;
162
}
163
if(ret && (hash_type != NULL)){
164
(*hash_type) = UNKNOWN_HASH_ALG;
165
}
166
return ret;
167
}
168
169
int gen_hash_get_hash_sizes(gen_hash_alg_type gen_hash_type, u8 *hlen, u8 *block_size)
170
{
171
int ret;
172
173
MUST_HAVE((hlen != NULL) && (block_size != NULL), ret, err);
174
175
switch(gen_hash_type){
176
case HASH_MD2:{
177
(*hlen) = MD2_DIGEST_SIZE;
178
(*block_size) = MD2_BLOCK_SIZE;
179
ret = 0;
180
break;
181
}
182
case HASH_MD4:{
183
(*hlen) = MD4_DIGEST_SIZE;
184
(*block_size) = MD4_BLOCK_SIZE;
185
ret = 0;
186
break;
187
}
188
case HASH_MD5:{
189
(*hlen) = MD5_DIGEST_SIZE;
190
(*block_size) = MD5_BLOCK_SIZE;
191
ret = 0;
192
break;
193
}
194
case HASH_SHA0:{
195
(*hlen) = SHA0_DIGEST_SIZE;
196
(*block_size) = SHA0_BLOCK_SIZE;
197
ret = 0;
198
break;
199
}
200
case HASH_SHA1:{
201
(*hlen) = SHA1_DIGEST_SIZE;
202
(*block_size) = SHA1_BLOCK_SIZE;
203
ret = 0;
204
break;
205
}
206
case HASH_MDC2_PADDING1:
207
case HASH_MDC2_PADDING2:{
208
(*hlen) = MDC2_DIGEST_SIZE;
209
(*block_size) = MDC2_BLOCK_SIZE;
210
ret = 0;
211
break;
212
}
213
case HASH_GOST34_11_94_NORM:
214
case HASH_GOST34_11_94_RFC4357:{
215
(*hlen) = GOSTR34_11_94_DIGEST_SIZE;
216
(*block_size) = GOSTR34_11_94_BLOCK_SIZE;
217
ret = 0;
218
break;
219
}
220
/* The default case falls back to a genuine libecc hash function */
221
default:{
222
const hash_mapping *hm;
223
hash_alg_type hash_type;
224
ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, hlen, block_size); EG(ret, err);
225
break;
226
}
227
}
228
229
err:
230
return ret;
231
}
232
233
int gen_hash_hfunc_scattered(const u8 **input, const u32 *ilen, u8 *digest, gen_hash_alg_type gen_hash_type)
234
{
235
int ret;
236
237
switch(gen_hash_type){
238
case HASH_MD2:{
239
ret = md2_scattered(input, ilen, digest); EG(ret, err);
240
break;
241
}
242
case HASH_MD4:{
243
ret = md4_scattered(input, ilen, digest); EG(ret, err);
244
break;
245
}
246
case HASH_MD5:{
247
ret = md5_scattered(input, ilen, digest); EG(ret, err);
248
break;
249
}
250
case HASH_SHA0:{
251
ret = sha0_scattered(input, ilen, digest); EG(ret, err);
252
break;
253
}
254
case HASH_SHA1:{
255
ret = sha1_scattered(input, ilen, digest); EG(ret, err);
256
break;
257
}
258
case HASH_MDC2_PADDING1:{
259
ret = mdc2_scattered_padding1(input, ilen, digest); EG(ret, err);
260
break;
261
}
262
case HASH_MDC2_PADDING2:{
263
ret = mdc2_scattered_padding2(input, ilen, digest); EG(ret, err);
264
break;
265
}
266
case HASH_GOST34_11_94_NORM:{
267
ret = gostr34_11_94_scattered_norm(input, ilen, digest); EG(ret, err);
268
break;
269
}
270
case HASH_GOST34_11_94_RFC4357:{
271
ret = gostr34_11_94_scattered_rfc4357(input, ilen, digest); EG(ret, err);
272
break;
273
}
274
/* The fallback should be libecc type */
275
default:{
276
const hash_mapping *hm;
277
hash_alg_type hash_type;
278
u8 hlen, block_size;
279
ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);
280
MUST_HAVE((hm != NULL), ret, err);
281
ret = hm->hfunc_scattered(input, ilen, digest); EG(ret, err);
282
break;
283
}
284
}
285
286
err:
287
return ret;
288
}
289
290
int gen_hash_hfunc(const u8 *input, u32 ilen, u8 *digest, gen_hash_alg_type gen_hash_type)
291
{
292
const u8 *inputs[2] = { input, NULL };
293
u32 ilens[2] = { ilen, 0 };
294
295
return gen_hash_hfunc_scattered(inputs, ilens, digest, gen_hash_type);
296
}
297
298
int gen_hash_init(gen_hash_context *ctx, gen_hash_alg_type gen_hash_type)
299
{
300
int ret;
301
302
MUST_HAVE((ctx != NULL), ret, err);
303
304
switch(gen_hash_type){
305
case HASH_MD2:{
306
ret = md2_init(&(ctx->md2ctx)); EG(ret, err);
307
break;
308
}
309
case HASH_MD4:{
310
ret = md4_init(&(ctx->md4ctx)); EG(ret, err);
311
break;
312
}
313
case HASH_MD5:{
314
ret = md5_init(&(ctx->md5ctx)); EG(ret, err);
315
break;
316
}
317
case HASH_SHA0:{
318
ret = sha0_init(&(ctx->sha0ctx)); EG(ret, err);
319
break;
320
}
321
case HASH_SHA1:{
322
ret = sha1_init(&(ctx->sha1ctx)); EG(ret, err);
323
break;
324
}
325
case HASH_MDC2_PADDING1:{
326
ret = mdc2_init(&(ctx->mdc2ctx)); EG(ret, err);
327
ret = mdc2_set_padding_type(&(ctx->mdc2ctx), ISOIEC10118_TYPE1); EG(ret, err);
328
break;
329
}
330
case HASH_MDC2_PADDING2:{
331
ret = mdc2_init(&(ctx->mdc2ctx)); EG(ret, err);
332
ret = mdc2_set_padding_type(&(ctx->mdc2ctx), ISOIEC10118_TYPE2); EG(ret, err);
333
break;
334
}
335
case HASH_GOST34_11_94_NORM:{
336
ret = gostr34_11_94_init(&(ctx->gostr34_11_94ctx)); EG(ret, err);
337
ret = gostr34_11_94_set_type(&(ctx->gostr34_11_94ctx), GOST34_11_94_NORM); EG(ret, err);
338
break;
339
}
340
case HASH_GOST34_11_94_RFC4357:{
341
ret = gostr34_11_94_init(&(ctx->gostr34_11_94ctx)); EG(ret, err);
342
ret = gostr34_11_94_set_type(&(ctx->gostr34_11_94ctx), GOST34_11_94_RFC4357); EG(ret, err);
343
break;
344
}
345
/* The fallback should be libecc type */
346
default:{
347
const hash_mapping *hm;
348
hash_alg_type hash_type;
349
u8 hlen, block_size;
350
ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);
351
MUST_HAVE((hm != NULL), ret, err);
352
ret = hm->hfunc_init(&(ctx->hctx)); EG(ret, err);
353
break;
354
}
355
}
356
357
err:
358
return ret;
359
}
360
361
int gen_hash_update(gen_hash_context *ctx, const u8 *chunk, u32 chunklen, gen_hash_alg_type gen_hash_type)
362
{
363
int ret;
364
365
MUST_HAVE((ctx != NULL), ret, err);
366
367
switch(gen_hash_type){
368
case HASH_MD2:{
369
ret = md2_update(&(ctx->md2ctx), chunk, chunklen); EG(ret, err);
370
break;
371
}
372
case HASH_MD4:{
373
ret = md4_update(&(ctx->md4ctx), chunk, chunklen); EG(ret, err);
374
break;
375
}
376
case HASH_MD5:{
377
ret = md5_update(&(ctx->md5ctx), chunk, chunklen); EG(ret, err);
378
break;
379
}
380
case HASH_SHA0:{
381
ret = sha0_update(&(ctx->sha0ctx), chunk, chunklen); EG(ret, err);
382
break;
383
}
384
case HASH_SHA1:{
385
ret = sha1_update(&(ctx->sha1ctx), chunk, chunklen); EG(ret, err);
386
break;
387
}
388
case HASH_MDC2_PADDING1:
389
case HASH_MDC2_PADDING2:{
390
ret = mdc2_update(&(ctx->mdc2ctx), chunk, chunklen); EG(ret, err);
391
break;
392
}
393
case HASH_GOST34_11_94_NORM:
394
case HASH_GOST34_11_94_RFC4357:{
395
ret = gostr34_11_94_update(&(ctx->gostr34_11_94ctx), chunk, chunklen); EG(ret, err);
396
break;
397
}
398
/* The fallback should be libecc type */
399
default:{
400
const hash_mapping *hm;
401
hash_alg_type hash_type;
402
u8 hlen, block_size;
403
ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);
404
MUST_HAVE((hm != NULL), ret, err);
405
ret = hm->hfunc_update(&(ctx->hctx), chunk, chunklen); EG(ret, err);
406
break;
407
}
408
}
409
410
err:
411
return ret;
412
}
413
414
int gen_hash_final(gen_hash_context *ctx, u8 *output, gen_hash_alg_type gen_hash_type)
415
{
416
int ret;
417
418
MUST_HAVE((ctx != NULL), ret, err);
419
420
switch(gen_hash_type){
421
case HASH_MD2:{
422
ret = md2_final(&(ctx->md2ctx), output); EG(ret, err);
423
break;
424
}
425
case HASH_MD4:{
426
ret = md4_final(&(ctx->md4ctx), output); EG(ret, err);
427
break;
428
}
429
case HASH_MD5:{
430
ret = md5_final(&(ctx->md5ctx), output); EG(ret, err);
431
break;
432
}
433
case HASH_SHA0:{
434
ret = sha0_final(&(ctx->sha0ctx), output); EG(ret, err);
435
break;
436
}
437
case HASH_SHA1:{
438
ret = sha1_final(&(ctx->sha1ctx), output); EG(ret, err);
439
break;
440
}
441
case HASH_MDC2_PADDING1:
442
case HASH_MDC2_PADDING2:{
443
ret = mdc2_final(&(ctx->mdc2ctx), output); EG(ret, err);
444
break;
445
}
446
case HASH_GOST34_11_94_NORM:
447
case HASH_GOST34_11_94_RFC4357:{
448
ret = gostr34_11_94_final(&(ctx->gostr34_11_94ctx), output); EG(ret, err);
449
break;
450
}
451
/* The fallback should be libecc type */
452
default:{
453
const hash_mapping *hm;
454
hash_alg_type hash_type;
455
u8 hlen, block_size;
456
ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);
457
MUST_HAVE((hm != NULL), ret, err);
458
ret = hm->hfunc_finalize(&(ctx->hctx), output); EG(ret, err);
459
break;
460
}
461
}
462
463
err:
464
return ret;
465
}
466
467
#ifdef HASH
468
#include <libecc/utils/print_buf.h>
469
int main(int argc, char *argv[])
470
{
471
int ret = 0;
472
unsigned int i;
473
474
const u8 input[] = "Now is the time for all ";
475
const u8 input2[] = "\x54\x68\x69\x73\x20\x69\x73\x20\x6D\x65\x73\x73\x61\x67\x65\x2C\x20\x6C\x65\x6E\x67\x74\x68\x3D\x33\x32\x20\x62\x79\x74\x65\x73";
476
const u8 input3[] = "";
477
const u8 input4[] = "Suppose the original message has length = 50 bytes";
478
u8 input5[128];
479
u8 output[32];
480
481
FORCE_USED_VAR(argc);
482
FORCE_USED_VAR(argv);
483
484
ret = local_memset(input5, 0, sizeof(input5)); EG(ret, err);
485
486
ret = gen_hash_hfunc(input, sizeof(input)-1, output, HASH_MDC2_PADDING1); EG(ret, err);
487
buf_print("mdc2 padding1", output, 16);
488
489
ret = gen_hash_hfunc(input, sizeof(input)-1, output, HASH_MDC2_PADDING2); EG(ret, err);
490
buf_print("mdc2 padding2", output, 16);
491
492
ret = gen_hash_hfunc(input2, sizeof(input2)-1, output, HASH_GOST34_11_94_NORM); EG(ret, err);
493
buf_print("gostr34_11_94 NORM", output, 32);
494
495
ret = gen_hash_hfunc(input3, sizeof(input3)-1, output, HASH_GOST34_11_94_NORM); EG(ret, err);
496
buf_print("gostr34_11_94 NORM", output, 32);
497
498
ret = gen_hash_hfunc(input4, sizeof(input4)-1, output, HASH_GOST34_11_94_NORM); EG(ret, err);
499
buf_print("gostr34_11_94 NORM", output, 32);
500
501
for(i = 0; i < sizeof(input5); i++){
502
input5[i] = 'U';
503
}
504
ret = gen_hash_hfunc(input5, sizeof(input5), output, HASH_GOST34_11_94_NORM); EG(ret, err);
505
buf_print("gostr34_11_94 NORM", output, 32);
506
507
err:
508
return ret;
509
}
510
#endif
511
512