Path: blob/main/crypto/libecc/src/examples/hash/hash.c
34889 views
/*1* Copyright (C) 2021 - This file is part of libecc project2*3* Authors:4* Ryad BENADJILA <[email protected]>5* Arnaud EBALARD <[email protected]>6*7* This software is licensed under a dual BSD and GPL v2 license.8* See LICENSE file at the root folder of the project.9*/10#include "hash.h"1112/* Get a libecc hash type and mapping from a generic hash type */13ATTRIBUTE_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)14{15int ret;16hash_alg_type htype = UNKNOWN_HASH_ALG;1718MUST_HAVE((hash_type != NULL) && (hm != NULL), ret, err);1920switch(gen_hash_type){21case HASH_SHA224:{22#ifdef WITH_HASH_SHA22423htype = SHA224;24#endif25break;26}27case HASH_SHA256:{28#ifdef WITH_HASH_SHA25629htype = SHA256;30#endif31break;32}33case HASH_SHA384:{34#ifdef WITH_HASH_SHA38435htype = SHA384;36#endif37break;38}39case HASH_SHA512:{40#ifdef WITH_HASH_SHA51241htype = SHA512;42#endif43break;44}45case HASH_SHA512_224:{46#ifdef WITH_HASH_SHA512_22447htype = SHA512_224;48#endif49break;50}51case HASH_SHA512_256:{52#ifdef WITH_HASH_SHA512_25653htype = SHA512_256;54#endif55break;56}57case HASH_SHA3_224:{58#ifdef WITH_HASH_SHA3_22459htype = SHA3_224;60#endif61break;62}63case HASH_SHA3_256:{64#ifdef WITH_HASH_SHA3_25665htype = SHA3_256;66#endif67break;68}69case HASH_SHA3_384:{70#ifdef WITH_HASH_SHA3_38471htype = SHA3_384;72#endif73break;74}75case HASH_SHA3_512:{76#ifdef WITH_HASH_SHA3_51277htype = SHA3_512;78#endif79break;80}81case HASH_SM3:{82#ifdef WITH_HASH_SM383htype = SM3;84#endif85break;86}87case HASH_STREEBOG256:{88#ifdef WITH_HASH_STREEBOG25689htype = STREEBOG256;90#endif91break;92}93case HASH_STREEBOG512:{94#ifdef WITH_HASH_STREEBOG51295htype = STREEBOG512;96#endif97break;98}99case HASH_SHAKE256:{100#ifdef WITH_HASH_SHAKE256101htype = SHAKE256;102#endif103break;104}105case HASH_RIPEMD160:{106#ifdef WITH_HASH_RIPEMD160107htype = RIPEMD160;108#endif109break;110}111case HASH_BELT_HASH:{112#ifdef WITH_HASH_BELT_HASH113htype = BELT_HASH;114#endif115break;116}117case HASH_BASH224:{118#ifdef WITH_HASH_BASH224119htype = BASH224;120#endif121break;122}123case HASH_BASH256:{124#ifdef WITH_HASH_BASH256125htype = BASH256;126#endif127break;128}129case HASH_BASH384:{130#ifdef WITH_HASH_BASH384131htype = BASH384;132#endif133break;134}135case HASH_BASH512:{136#ifdef WITH_HASH_BASH512137htype = BASH512;138#endif139break;140}141142default:{143htype = UNKNOWN_HASH_ALG;144break;145}146}147if(htype != UNKNOWN_HASH_ALG){148(*hash_type) = htype;149ret = get_hash_by_type(htype, hm); EG(ret, err);150ret = get_hash_sizes(htype, hlen, block_size); EG(ret, err);151MUST_HAVE(((*hlen) <= MAX_DIGEST_SIZE), ret, err);152ret = 0;153}154else{155ret = -1;156}157158err:159if(ret && (hm != NULL)){160(*hm) = NULL;161}162if(ret && (hash_type != NULL)){163(*hash_type) = UNKNOWN_HASH_ALG;164}165return ret;166}167168int gen_hash_get_hash_sizes(gen_hash_alg_type gen_hash_type, u8 *hlen, u8 *block_size)169{170int ret;171172MUST_HAVE((hlen != NULL) && (block_size != NULL), ret, err);173174switch(gen_hash_type){175case HASH_MD2:{176(*hlen) = MD2_DIGEST_SIZE;177(*block_size) = MD2_BLOCK_SIZE;178ret = 0;179break;180}181case HASH_MD4:{182(*hlen) = MD4_DIGEST_SIZE;183(*block_size) = MD4_BLOCK_SIZE;184ret = 0;185break;186}187case HASH_MD5:{188(*hlen) = MD5_DIGEST_SIZE;189(*block_size) = MD5_BLOCK_SIZE;190ret = 0;191break;192}193case HASH_SHA0:{194(*hlen) = SHA0_DIGEST_SIZE;195(*block_size) = SHA0_BLOCK_SIZE;196ret = 0;197break;198}199case HASH_SHA1:{200(*hlen) = SHA1_DIGEST_SIZE;201(*block_size) = SHA1_BLOCK_SIZE;202ret = 0;203break;204}205case HASH_MDC2_PADDING1:206case HASH_MDC2_PADDING2:{207(*hlen) = MDC2_DIGEST_SIZE;208(*block_size) = MDC2_BLOCK_SIZE;209ret = 0;210break;211}212case HASH_GOST34_11_94_NORM:213case HASH_GOST34_11_94_RFC4357:{214(*hlen) = GOSTR34_11_94_DIGEST_SIZE;215(*block_size) = GOSTR34_11_94_BLOCK_SIZE;216ret = 0;217break;218}219/* The default case falls back to a genuine libecc hash function */220default:{221const hash_mapping *hm;222hash_alg_type hash_type;223ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, hlen, block_size); EG(ret, err);224break;225}226}227228err:229return ret;230}231232int gen_hash_hfunc_scattered(const u8 **input, const u32 *ilen, u8 *digest, gen_hash_alg_type gen_hash_type)233{234int ret;235236switch(gen_hash_type){237case HASH_MD2:{238ret = md2_scattered(input, ilen, digest); EG(ret, err);239break;240}241case HASH_MD4:{242ret = md4_scattered(input, ilen, digest); EG(ret, err);243break;244}245case HASH_MD5:{246ret = md5_scattered(input, ilen, digest); EG(ret, err);247break;248}249case HASH_SHA0:{250ret = sha0_scattered(input, ilen, digest); EG(ret, err);251break;252}253case HASH_SHA1:{254ret = sha1_scattered(input, ilen, digest); EG(ret, err);255break;256}257case HASH_MDC2_PADDING1:{258ret = mdc2_scattered_padding1(input, ilen, digest); EG(ret, err);259break;260}261case HASH_MDC2_PADDING2:{262ret = mdc2_scattered_padding2(input, ilen, digest); EG(ret, err);263break;264}265case HASH_GOST34_11_94_NORM:{266ret = gostr34_11_94_scattered_norm(input, ilen, digest); EG(ret, err);267break;268}269case HASH_GOST34_11_94_RFC4357:{270ret = gostr34_11_94_scattered_rfc4357(input, ilen, digest); EG(ret, err);271break;272}273/* The fallback should be libecc type */274default:{275const hash_mapping *hm;276hash_alg_type hash_type;277u8 hlen, block_size;278ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);279MUST_HAVE((hm != NULL), ret, err);280ret = hm->hfunc_scattered(input, ilen, digest); EG(ret, err);281break;282}283}284285err:286return ret;287}288289int gen_hash_hfunc(const u8 *input, u32 ilen, u8 *digest, gen_hash_alg_type gen_hash_type)290{291const u8 *inputs[2] = { input, NULL };292u32 ilens[2] = { ilen, 0 };293294return gen_hash_hfunc_scattered(inputs, ilens, digest, gen_hash_type);295}296297int gen_hash_init(gen_hash_context *ctx, gen_hash_alg_type gen_hash_type)298{299int ret;300301MUST_HAVE((ctx != NULL), ret, err);302303switch(gen_hash_type){304case HASH_MD2:{305ret = md2_init(&(ctx->md2ctx)); EG(ret, err);306break;307}308case HASH_MD4:{309ret = md4_init(&(ctx->md4ctx)); EG(ret, err);310break;311}312case HASH_MD5:{313ret = md5_init(&(ctx->md5ctx)); EG(ret, err);314break;315}316case HASH_SHA0:{317ret = sha0_init(&(ctx->sha0ctx)); EG(ret, err);318break;319}320case HASH_SHA1:{321ret = sha1_init(&(ctx->sha1ctx)); EG(ret, err);322break;323}324case HASH_MDC2_PADDING1:{325ret = mdc2_init(&(ctx->mdc2ctx)); EG(ret, err);326ret = mdc2_set_padding_type(&(ctx->mdc2ctx), ISOIEC10118_TYPE1); EG(ret, err);327break;328}329case HASH_MDC2_PADDING2:{330ret = mdc2_init(&(ctx->mdc2ctx)); EG(ret, err);331ret = mdc2_set_padding_type(&(ctx->mdc2ctx), ISOIEC10118_TYPE2); EG(ret, err);332break;333}334case HASH_GOST34_11_94_NORM:{335ret = gostr34_11_94_init(&(ctx->gostr34_11_94ctx)); EG(ret, err);336ret = gostr34_11_94_set_type(&(ctx->gostr34_11_94ctx), GOST34_11_94_NORM); EG(ret, err);337break;338}339case HASH_GOST34_11_94_RFC4357:{340ret = gostr34_11_94_init(&(ctx->gostr34_11_94ctx)); EG(ret, err);341ret = gostr34_11_94_set_type(&(ctx->gostr34_11_94ctx), GOST34_11_94_RFC4357); EG(ret, err);342break;343}344/* The fallback should be libecc type */345default:{346const hash_mapping *hm;347hash_alg_type hash_type;348u8 hlen, block_size;349ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);350MUST_HAVE((hm != NULL), ret, err);351ret = hm->hfunc_init(&(ctx->hctx)); EG(ret, err);352break;353}354}355356err:357return ret;358}359360int gen_hash_update(gen_hash_context *ctx, const u8 *chunk, u32 chunklen, gen_hash_alg_type gen_hash_type)361{362int ret;363364MUST_HAVE((ctx != NULL), ret, err);365366switch(gen_hash_type){367case HASH_MD2:{368ret = md2_update(&(ctx->md2ctx), chunk, chunklen); EG(ret, err);369break;370}371case HASH_MD4:{372ret = md4_update(&(ctx->md4ctx), chunk, chunklen); EG(ret, err);373break;374}375case HASH_MD5:{376ret = md5_update(&(ctx->md5ctx), chunk, chunklen); EG(ret, err);377break;378}379case HASH_SHA0:{380ret = sha0_update(&(ctx->sha0ctx), chunk, chunklen); EG(ret, err);381break;382}383case HASH_SHA1:{384ret = sha1_update(&(ctx->sha1ctx), chunk, chunklen); EG(ret, err);385break;386}387case HASH_MDC2_PADDING1:388case HASH_MDC2_PADDING2:{389ret = mdc2_update(&(ctx->mdc2ctx), chunk, chunklen); EG(ret, err);390break;391}392case HASH_GOST34_11_94_NORM:393case HASH_GOST34_11_94_RFC4357:{394ret = gostr34_11_94_update(&(ctx->gostr34_11_94ctx), chunk, chunklen); EG(ret, err);395break;396}397/* The fallback should be libecc type */398default:{399const hash_mapping *hm;400hash_alg_type hash_type;401u8 hlen, block_size;402ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);403MUST_HAVE((hm != NULL), ret, err);404ret = hm->hfunc_update(&(ctx->hctx), chunk, chunklen); EG(ret, err);405break;406}407}408409err:410return ret;411}412413int gen_hash_final(gen_hash_context *ctx, u8 *output, gen_hash_alg_type gen_hash_type)414{415int ret;416417MUST_HAVE((ctx != NULL), ret, err);418419switch(gen_hash_type){420case HASH_MD2:{421ret = md2_final(&(ctx->md2ctx), output); EG(ret, err);422break;423}424case HASH_MD4:{425ret = md4_final(&(ctx->md4ctx), output); EG(ret, err);426break;427}428case HASH_MD5:{429ret = md5_final(&(ctx->md5ctx), output); EG(ret, err);430break;431}432case HASH_SHA0:{433ret = sha0_final(&(ctx->sha0ctx), output); EG(ret, err);434break;435}436case HASH_SHA1:{437ret = sha1_final(&(ctx->sha1ctx), output); EG(ret, err);438break;439}440case HASH_MDC2_PADDING1:441case HASH_MDC2_PADDING2:{442ret = mdc2_final(&(ctx->mdc2ctx), output); EG(ret, err);443break;444}445case HASH_GOST34_11_94_NORM:446case HASH_GOST34_11_94_RFC4357:{447ret = gostr34_11_94_final(&(ctx->gostr34_11_94ctx), output); EG(ret, err);448break;449}450/* The fallback should be libecc type */451default:{452const hash_mapping *hm;453hash_alg_type hash_type;454u8 hlen, block_size;455ret = get_libecc_hash(gen_hash_type, &hash_type, &hm, &hlen, &block_size); EG(ret, err);456MUST_HAVE((hm != NULL), ret, err);457ret = hm->hfunc_finalize(&(ctx->hctx), output); EG(ret, err);458break;459}460}461462err:463return ret;464}465466#ifdef HASH467#include <libecc/utils/print_buf.h>468int main(int argc, char *argv[])469{470int ret = 0;471unsigned int i;472473const u8 input[] = "Now is the time for all ";474const 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";475const u8 input3[] = "";476const u8 input4[] = "Suppose the original message has length = 50 bytes";477u8 input5[128];478u8 output[32];479480FORCE_USED_VAR(argc);481FORCE_USED_VAR(argv);482483ret = local_memset(input5, 0, sizeof(input5)); EG(ret, err);484485ret = gen_hash_hfunc(input, sizeof(input)-1, output, HASH_MDC2_PADDING1); EG(ret, err);486buf_print("mdc2 padding1", output, 16);487488ret = gen_hash_hfunc(input, sizeof(input)-1, output, HASH_MDC2_PADDING2); EG(ret, err);489buf_print("mdc2 padding2", output, 16);490491ret = gen_hash_hfunc(input2, sizeof(input2)-1, output, HASH_GOST34_11_94_NORM); EG(ret, err);492buf_print("gostr34_11_94 NORM", output, 32);493494ret = gen_hash_hfunc(input3, sizeof(input3)-1, output, HASH_GOST34_11_94_NORM); EG(ret, err);495buf_print("gostr34_11_94 NORM", output, 32);496497ret = gen_hash_hfunc(input4, sizeof(input4)-1, output, HASH_GOST34_11_94_NORM); EG(ret, err);498buf_print("gostr34_11_94 NORM", output, 32);499500for(i = 0; i < sizeof(input5); i++){501input5[i] = 'U';502}503ret = gen_hash_hfunc(input5, sizeof(input5), output, HASH_GOST34_11_94_NORM); EG(ret, err);504buf_print("gostr34_11_94 NORM", output, 32);505506err:507return ret;508}509#endif510511512