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