commit
81419d8f00
@ -1120,7 +1120,7 @@ parse_rc_param(fko_cli_options_t *options, const char *var_name, char * val)
|
||||
if(tmpint < 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_WARNING,
|
||||
"HMAC_DIGEST_TYPE argument '%s' must be one of {md5,sha1,sha256,sha384,sha512}",
|
||||
"HMAC_DIGEST_TYPE argument '%s' must be one of {md5,sha1,sha256,sha384,sha512,sha3_256,sha3_512}",
|
||||
val);
|
||||
parse_error = -1;
|
||||
}
|
||||
@ -2157,7 +2157,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
if((options->hmac_type = hmac_digest_strtoint(optarg)) < 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"* Invalid hmac digest type: %s, use {md5,sha1,sha256,sha384,sha512}",
|
||||
"* Invalid hmac digest type: %s, use {md5,sha1,sha256,sha384,sha512,sha3_256,sha3_512}",
|
||||
optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -2208,7 +2208,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
if((options->digest_type = digest_strtoint(optarg)) < 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR,
|
||||
"* Invalid digest type: %s, use {md5,sha1,sha256,sha384,sha512}",
|
||||
"* Invalid digest type: %s, use {md5,sha1,sha256,sha384,sha512,sha3_256,sha3_512}",
|
||||
optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -182,6 +182,10 @@ digest_strtoint(const char *dt_str)
|
||||
return(FKO_DIGEST_SHA384);
|
||||
else if(strcasecmp(dt_str, "sha512") == 0)
|
||||
return(FKO_DIGEST_SHA512);
|
||||
else if(strcasecmp(dt_str, "sha3_256") == 0)
|
||||
return(FKO_DIGEST_SHA3_512);
|
||||
else if(strcasecmp(dt_str, "sha3_512") == 0)
|
||||
return(FKO_DIGEST_SHA3_512);
|
||||
else
|
||||
return(-1);
|
||||
}
|
||||
@ -222,6 +226,12 @@ digest_inttostr(int digest, char* digest_str, size_t digest_size)
|
||||
case FKO_DIGEST_SHA512:
|
||||
strlcpy(digest_str, "SHA512", digest_size);
|
||||
break;
|
||||
case FKO_DIGEST_SHA3_256:
|
||||
strlcpy(digest_str, "SHA3_256", digest_size);
|
||||
break;
|
||||
case FKO_DIGEST_SHA3_512:
|
||||
strlcpy(digest_str, "SHA3_512", digest_size);
|
||||
break;
|
||||
default:
|
||||
strlcpy(digest_str, "Unknown", digest_size);
|
||||
digest_not_valid = -1;
|
||||
@ -244,6 +254,10 @@ hmac_digest_strtoint(const char *dt_str)
|
||||
return(FKO_HMAC_SHA384);
|
||||
else if(strcasecmp(dt_str, "sha512") == 0)
|
||||
return(FKO_HMAC_SHA512);
|
||||
else if(strcasecmp(dt_str, "sha3_256") == 0)
|
||||
return(FKO_HMAC_SHA3_256);
|
||||
else if(strcasecmp(dt_str, "sha3_512") == 0)
|
||||
return(FKO_HMAC_SHA3_512);
|
||||
else
|
||||
return(-1);
|
||||
}
|
||||
@ -322,6 +336,12 @@ hmac_digest_inttostr(int digest, char* digest_str, size_t digest_size)
|
||||
case FKO_HMAC_SHA512:
|
||||
strlcpy(digest_str, "SHA512", digest_size);
|
||||
break;
|
||||
case FKO_HMAC_SHA3_256:
|
||||
strlcpy(digest_str, "SHA3_256", digest_size);
|
||||
break;
|
||||
case FKO_HMAC_SHA3_512:
|
||||
strlcpy(digest_str, "SHA3_512", digest_size);
|
||||
break;
|
||||
default:
|
||||
strlcpy(digest_str, "Unknown", digest_size);
|
||||
digest_not_valid = -1;
|
||||
|
||||
@ -7,7 +7,7 @@ libfko_source_files = \
|
||||
fko_message.h fko_nat_access.c fko_rand_value.c fko_server_auth.c \
|
||||
fko.h fko_limits.h fko_timestamp.c fko_hmac.c hmac.c hmac.h \
|
||||
fko_user.c fko_user.h md5.c md5.h rijndael.c rijndael.h sha1.c \
|
||||
sha1.h sha2.c sha2.h fko_context.h fko_state.h \
|
||||
sha1.h sha2.c sha2.h sha3.c sha3.h fko_context.h fko_state.h \
|
||||
gpgme_funcs.c gpgme_funcs.h
|
||||
|
||||
|
||||
|
||||
@ -49,6 +49,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_C_UNIT_TESTS
|
||||
DECLARE_TEST_SUITE(digest_test, "Cipher functions test suite");
|
||||
#endif
|
||||
|
||||
/* Get random data.
|
||||
*/
|
||||
void
|
||||
@ -414,4 +418,247 @@ add_gpg_prefix(fko_ctx_t ctx)
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef HAVE_C_UNIT_TESTS
|
||||
|
||||
|
||||
|
||||
DECLARE_UTEST(test_aes_ecb_128, "aes ecb 128 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char in[1024] = {0};
|
||||
unsigned char out[1024] = {0};
|
||||
unsigned char expected_out1[1024] = {0};
|
||||
unsigned char expected_out2[1024] = {0};
|
||||
unsigned char expected_out3[1024] = {0};
|
||||
unsigned char expected_out4[1024] = {0};
|
||||
|
||||
memcpy(expected_out1, "\x3a\xd7\x7b\xb4\x0d\x7a\x36\x60\xa8\x9e\xca\xf3\x24\x66\xef\x97", 16);
|
||||
memcpy(expected_out2, "\xf5\xd3\xd5\x85\x03\xb9\x69\x9d\xe7\x85\x89\x5a\x96\xfd\xba\xaf", 16);
|
||||
memcpy(expected_out3, "\x43\xb1\xcd\x7f\x59\x8e\xce\x23\x88\x1b\x00\xe3\xed\x03\x06\x88", 16);
|
||||
memcpy(expected_out4, "\x7b\x0c\x78\x5e\x27\xe8\xad\x3f\x82\x23\x20\x71\x04\x72\x5d\xd4", 16);
|
||||
memcpy(ctx.key, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16);
|
||||
rijndael_setup(&ctx, 16, ctx.key);
|
||||
|
||||
memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out1, 16) == 0);
|
||||
|
||||
memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out2, 16) == 0);
|
||||
|
||||
memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out3, 16) == 0);
|
||||
|
||||
memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out4, 16) == 0);
|
||||
|
||||
}
|
||||
DECLARE_UTEST(test_aes_ecb_192, "aes ecb 192 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char in[1024] = {0};
|
||||
unsigned char out[1024] = {0};
|
||||
unsigned char expected_out1[1024] = {0};
|
||||
unsigned char expected_out2[1024] = {0};
|
||||
unsigned char expected_out3[1024] = {0};
|
||||
unsigned char expected_out4[1024] = {0};
|
||||
|
||||
memcpy(expected_out1, "\xbd\x33\x4f\x1d\x6e\x45\xf2\x5f\xf7\x12\xa2\x14\x57\x1f\xa5\xcc", 16);
|
||||
memcpy(expected_out2, "\x97\x41\x04\x84\x6d\x0a\xd3\xad\x77\x34\xec\xb3\xec\xee\x4e\xef", 16);
|
||||
memcpy(expected_out3, "\xef\x7a\xfd\x22\x70\xe2\xe6\x0a\xdc\xe0\xba\x2f\xac\xe6\x44\x4e", 16);
|
||||
memcpy(expected_out4, "\x9a\x4b\x41\xba\x73\x8d\x6c\x72\xfb\x16\x69\x16\x03\xc1\x8e\x0e", 16);
|
||||
memcpy(ctx.key, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24);
|
||||
rijndael_setup(&ctx, 24, ctx.key);
|
||||
|
||||
memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out1, 16) == 0);
|
||||
|
||||
memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out2, 16) == 0);
|
||||
|
||||
memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out3, 16) == 0);
|
||||
|
||||
memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out4, 16) == 0);
|
||||
|
||||
}
|
||||
DECLARE_UTEST(test_aes_ecb_256, "aes ecb 256 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char in[1024] = {0};
|
||||
unsigned char out[1024] = {0};
|
||||
unsigned char expected_out1[1024] = {0};
|
||||
unsigned char expected_out2[1024] = {0};
|
||||
unsigned char expected_out3[1024] = {0};
|
||||
unsigned char expected_out4[1024] = {0};
|
||||
|
||||
memcpy(expected_out1, "\xf3\xee\xd1\xbd\xb5\xd2\xa0\x3c\x06\x4b\x5a\x7e\x3d\xb1\x81\xf8", 16);
|
||||
memcpy(expected_out2, "\x59\x1c\xcb\x10\xd4\x10\xed\x26\xdc\x5b\xa7\x4a\x31\x36\x28\x70", 16);
|
||||
memcpy(expected_out3, "\xb6\xed\x21\xb9\x9c\xa6\xf4\xf9\xf1\x53\xe7\xb1\xbe\xaf\xed\x1d", 16);
|
||||
memcpy(expected_out4, "\x23\x30\x4b\x7a\x39\xf9\xf3\xff\x06\x7d\x8d\x8f\x9e\x24\xec\xc7", 16);
|
||||
memcpy(ctx.key, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32);
|
||||
rijndael_setup(&ctx, 32, ctx.key);
|
||||
|
||||
memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out1, 16) == 0);
|
||||
|
||||
memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out2, 16) == 0);
|
||||
|
||||
memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out3, 16) == 0);
|
||||
|
||||
memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16);
|
||||
rijndael_encrypt(&ctx, in, out);
|
||||
CU_ASSERT(memcmp(out, expected_out4, 16) == 0);
|
||||
|
||||
}
|
||||
|
||||
DECLARE_UTEST(test_aes_cbc_128, "aes cbc 128 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
{ //would like to test rij_encrypt against known test vectors, but the method of generating the key and iv make this impossible.
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char in[1024] = {0};
|
||||
unsigned char out[1024] = {0};
|
||||
unsigned char expected_out1[1024] = {0};
|
||||
unsigned char expected_out2[1024] = {0};
|
||||
unsigned char expected_out3[1024] = {0};
|
||||
unsigned char expected_out4[1024] = {0};
|
||||
|
||||
memcpy(ctx.key, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16);
|
||||
memcpy(expected_out1, "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d", 16);
|
||||
memcpy(expected_out2, "\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2", 16);
|
||||
memcpy(expected_out3, "\x73\xbe\xd6\xb8\xe3\xc1\x74\x3b\x71\x16\xe6\x9e\x22\x22\x95\x16", 16);
|
||||
memcpy(expected_out4, "\x3f\xf1\xca\xa1\x68\x1f\xac\x09\x12\x0e\xca\x30\x75\x86\xe1\xa7", 16);
|
||||
ctx.mode = MODE_CBC;
|
||||
rijndael_setup(&ctx, 16, ctx.key);
|
||||
|
||||
memcpy(ctx.iv, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16);
|
||||
memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out1, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, "\x76\x49\xAB\xAC\x81\x19\xB2\x46\xCE\xE9\x8E\x9B\x12\xE9\x19\x7D", 16);
|
||||
memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out2, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, "\x50\x86\xCB\x9B\x50\x72\x19\xEE\x95\xDB\x11\x3A\x91\x76\x78\xB2", 16);
|
||||
memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out3, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, "\x73\xBE\xD6\xB8\xE3\xC1\x74\x3B\x71\x16\xE6\x9E\x22\x22\x95\x16", 16);
|
||||
memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out4, 16) == 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
DECLARE_UTEST(test_aes_cbc_192, "aes cbc 192 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
{ //would like to test rij_encrypt against known test vectors, but the method of generating the key and iv make this impossible.
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char in[1024] = {0};
|
||||
unsigned char out[1024] = {0};
|
||||
unsigned char expected_out1[1024] = {0};
|
||||
unsigned char expected_out2[1024] = {0};
|
||||
unsigned char expected_out3[1024] = {0};
|
||||
unsigned char expected_out4[1024] = {0};
|
||||
|
||||
memcpy(ctx.key, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24);
|
||||
memcpy(expected_out1, "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d\x71\x78\x18\x3a\x9f\xa0\x71\xe8", 16);
|
||||
memcpy(expected_out2, "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4\xe5\xe7\x38\x76\x3f\x69\x14\x5a", 16);
|
||||
memcpy(expected_out3, "\x57\x1b\x24\x20\x12\xfb\x7a\xe0\x7f\xa9\xba\xac\x3d\xf1\x02\xe0", 16);
|
||||
memcpy(expected_out4, "\x08\xb0\xe2\x79\x88\x59\x88\x81\xd9\x20\xa9\xe6\x4f\x56\x15\xcd", 16);
|
||||
ctx.mode = MODE_CBC;
|
||||
rijndael_setup(&ctx, 24, ctx.key);
|
||||
|
||||
memcpy(ctx.iv, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16);
|
||||
memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out1, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, out, 16);
|
||||
memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out2, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, out, 16);
|
||||
memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out3, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, out, 16);
|
||||
memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out4, 16) == 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
DECLARE_UTEST(test_aes_cbc_256, "aes cbc 256 test vectors") //http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128
|
||||
{ //would like to test rij_encrypt against known test vectors, but the method of generating the key and iv make this impossible.
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char in[1024] = {0};
|
||||
unsigned char out[1024] = {0};
|
||||
unsigned char expected_out1[1024] = {0};
|
||||
unsigned char expected_out2[1024] = {0};
|
||||
unsigned char expected_out3[1024] = {0};
|
||||
unsigned char expected_out4[1024] = {0};
|
||||
|
||||
memcpy(ctx.key, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32);
|
||||
memcpy(expected_out1, "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6", 16);
|
||||
memcpy(expected_out2, "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d\x67\x9f\x77\x7b\xc6\x70\x2c\x7d", 16);
|
||||
memcpy(expected_out3, "\x39\xf2\x33\x69\xa9\xd9\xba\xcf\xa5\x30\xe2\x63\x04\x23\x14\x61", 16);
|
||||
memcpy(expected_out4, "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc\xda\x6c\x19\x07\x8c\x6a\x9d\x1b", 16);
|
||||
ctx.mode = MODE_CBC;
|
||||
rijndael_setup(&ctx, 32, ctx.key);
|
||||
|
||||
memcpy(ctx.iv, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16);
|
||||
memcpy(in, "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out1, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, out, 16);
|
||||
memcpy(in, "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out2, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, out, 16);
|
||||
memcpy(in, "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out3, 16) == 0);
|
||||
|
||||
memcpy(ctx.iv, out, 16);
|
||||
memcpy(in, "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16);
|
||||
block_encrypt(&ctx, in, 16, out, ctx.iv);
|
||||
CU_ASSERT(memcmp(out, expected_out4, 16) == 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int register_ts_aes_test(void)
|
||||
{
|
||||
ts_init(&TEST_SUITE(digest_test), TEST_SUITE_DESCR(digest_test), NULL, NULL);
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_ecb_128), UTEST_DESCR(test_aes_ecb_128));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_ecb_192), UTEST_DESCR(test_aes_ecb_192));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_ecb_256), UTEST_DESCR(test_aes_ecb_256));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_cbc_128), UTEST_DESCR(test_aes_cbc_128));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_cbc_192), UTEST_DESCR(test_aes_cbc_192));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_aes_cbc_256), UTEST_DESCR(test_aes_cbc_256));
|
||||
|
||||
return register_ts(&TEST_SUITE(digest_test));
|
||||
}
|
||||
#endif
|
||||
/***EOF***/
|
||||
|
||||
423
lib/digest.c
423
lib/digest.c
@ -28,7 +28,9 @@
|
||||
#include "fko_common.h"
|
||||
#include "digest.h"
|
||||
#include "base64.h"
|
||||
|
||||
#ifdef HAVE_C_UNIT_TESTS
|
||||
DECLARE_TEST_SUITE(digest_test, "digest functions test suite");
|
||||
#endif
|
||||
/* Compute MD5 hash on in and store result in out.
|
||||
*/
|
||||
void
|
||||
@ -154,4 +156,423 @@ sha512_base64(char *out, unsigned char *in, size_t size)
|
||||
strip_b64_eq(out);
|
||||
}
|
||||
|
||||
void
|
||||
sha3_256(unsigned char *out, unsigned char *in, size_t size)
|
||||
{
|
||||
FIPS202_SHA3_256(in, size, out);
|
||||
}
|
||||
|
||||
void
|
||||
sha3_256_base64(char *out, unsigned char *in, size_t size)
|
||||
{
|
||||
uint8_t md[SHA3_256_DIGEST_LEN];
|
||||
|
||||
FIPS202_SHA3_256(in, size, md);
|
||||
b64_encode(md, out, SHA3_256_DIGEST_LEN);
|
||||
|
||||
strip_b64_eq(out);
|
||||
|
||||
}
|
||||
void
|
||||
sha3_512(unsigned char *out, unsigned char *in, size_t size)
|
||||
{
|
||||
FIPS202_SHA3_512(in, size, out);
|
||||
}
|
||||
|
||||
void
|
||||
sha3_512_base64(char *out, unsigned char *in, size_t size)
|
||||
{
|
||||
uint8_t md[SHA3_512_DIGEST_LEN];
|
||||
|
||||
FIPS202_SHA3_512(in, size, md);
|
||||
b64_encode(md, out, SHA3_512_DIGEST_LEN);
|
||||
|
||||
strip_b64_eq(out);
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_C_UNIT_TESTS
|
||||
|
||||
DECLARE_UTEST(test_md5, "md5 test vectors") //https://tools.ietf.org/html/rfc1321.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
char expected_digest5[1024] = {0};
|
||||
char expected_digest6[1024] = {0};
|
||||
char expected_digest7[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(expected_digest1, "d41d8cd98f00b204e9800998ecf8427e");
|
||||
strcpy(expected_digest2, "0cc175b9c0f1b6a831c399e269772661");
|
||||
strcpy(expected_digest3, "900150983cd24fb0d6963f7d28e17f72");
|
||||
strcpy(expected_digest4, "f96b697d7cb7938d525a2f31aaf161d0");
|
||||
strcpy(expected_digest5, "c3fcd3d76192e4007dfb496cca67e13b");
|
||||
strcpy(expected_digest6, "d174ab98d277d9f5a5611c2c9f419d9f");
|
||||
strcpy(expected_digest7, "57edf4a22be3c955ac49da2e2107b67a");
|
||||
|
||||
strcpy(msg, "");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, MD5_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "a");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, MD5_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abc");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, MD5_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "message digest");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, MD5_DIGEST_LEN) == 0);
|
||||
strcpy(msg, "abcdefghijklmnopqrstuvwxyz");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest5, MD5_DIGEST_LEN) == 0);
|
||||
strcpy(msg, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest6, MD5_DIGEST_LEN) == 0);
|
||||
strcpy(msg, "12345678901234567890123456789012345678901234567890123456789012345678901234567890");
|
||||
md5(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest7, MD5_DIGEST_LEN) == 0);
|
||||
|
||||
}
|
||||
|
||||
DECLARE_UTEST(test_sha1, "sha1 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(msg, "abc");
|
||||
strcpy(expected_digest1, "a9993e364706816aba3e25717850c26c9cd0d89d");
|
||||
sha1(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA1_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA1_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(expected_digest2, "da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
||||
sha1(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA1_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA1_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||
strcpy(expected_digest3, "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
|
||||
sha1(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA1_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA1_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||
strcpy(expected_digest4, "a49b2446a02c645bf419f995b67091253a04a259");
|
||||
sha1(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA1_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA1_DIGEST_LEN) == 0);
|
||||
|
||||
}
|
||||
DECLARE_UTEST(test_sha256, "sha-256 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(msg, "abc");
|
||||
strcpy(expected_digest1, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
|
||||
sha256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA256_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(expected_digest2, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||
sha256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA256_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||
strcpy(expected_digest3, "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
|
||||
sha256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA256_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||
strcpy(expected_digest4, "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1");
|
||||
sha256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA256_DIGEST_LEN) == 0);
|
||||
}
|
||||
DECLARE_UTEST(test_sha384, "sha-384 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(msg, "abc");
|
||||
strcpy(expected_digest1, "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7");
|
||||
sha384(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA384_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA384_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(expected_digest2, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b");
|
||||
sha384(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA384_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA384_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||
strcpy(expected_digest3, "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b");
|
||||
sha384(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA384_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA384_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||
strcpy(expected_digest4, "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039");
|
||||
sha384(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA384_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA384_DIGEST_LEN) == 0);
|
||||
|
||||
}
|
||||
DECLARE_UTEST(test_sha512, "sha-512 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(msg, "abc");
|
||||
strcpy(expected_digest1, "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
|
||||
sha512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA512_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(expected_digest2, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
|
||||
sha512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA512_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||
strcpy(expected_digest3, "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
|
||||
sha512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA512_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||
strcpy(expected_digest4, "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
|
||||
sha512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA512_DIGEST_LEN) == 0);
|
||||
|
||||
}
|
||||
|
||||
DECLARE_UTEST(test_sha3_256, "sha3_256 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(msg, "abc");
|
||||
strcpy(expected_digest1, "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532");
|
||||
sha3_256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA3_256_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(expected_digest2, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a");
|
||||
sha3_256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA3_256_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||
strcpy(expected_digest3, "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376");
|
||||
sha3_256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA3_256_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||
strcpy(expected_digest4, "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18");
|
||||
sha3_256(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_256_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA3_256_DIGEST_LEN) == 0);
|
||||
|
||||
}
|
||||
|
||||
DECLARE_UTEST(test_sha3_512, "sha3_512 test vectors") //http://www.di-mgt.com.au/sha_testvectors.html
|
||||
{
|
||||
char msg[1024] = {0};
|
||||
unsigned char digest[1024] = {0};
|
||||
char digest_txt[1024] = {0};
|
||||
char expected_digest1[1024] = {0};
|
||||
char expected_digest2[1024] = {0};
|
||||
char expected_digest3[1024] = {0};
|
||||
char expected_digest4[1024] = {0};
|
||||
int i = 0;
|
||||
|
||||
strcpy(msg, "abc");
|
||||
strcpy(expected_digest1, "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0");
|
||||
sha3_512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest1, SHA3_512_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "");
|
||||
strcpy(expected_digest2, "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26");
|
||||
sha3_512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest2, SHA3_512_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||
strcpy(expected_digest3, "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e");
|
||||
sha3_512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest3, SHA3_512_DIGEST_LEN) == 0);
|
||||
|
||||
strcpy(msg, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||
strcpy(expected_digest4, "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185");
|
||||
sha3_512(digest, (unsigned char *)msg, strlen(msg));
|
||||
for ( i = 0; i < SHA3_512_DIGEST_LEN; i++)
|
||||
{
|
||||
sprintf(digest_txt + (2 * i), "%02x", digest[i]);
|
||||
}
|
||||
CU_ASSERT(memcmp(digest_txt, expected_digest4, SHA3_512_DIGEST_LEN) == 0);
|
||||
|
||||
}
|
||||
|
||||
int register_ts_digest_test(void)
|
||||
{
|
||||
ts_init(&TEST_SUITE(digest_test), TEST_SUITE_DESCR(digest_test), NULL, NULL);
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_md5), UTEST_DESCR(test_md5));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha1), UTEST_DESCR(test_sha1));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha256), UTEST_DESCR(test_sha256));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha384), UTEST_DESCR(test_sha384));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha512), UTEST_DESCR(test_sha512));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha3_256), UTEST_DESCR(test_sha3_256));
|
||||
ts_add_utest(&TEST_SUITE(digest_test), UTEST_FCT(test_sha3_512), UTEST_DESCR(test_sha3_512));
|
||||
|
||||
return register_ts(&TEST_SUITE(digest_test));
|
||||
}
|
||||
|
||||
#endif /* HAVE_C_UNIT_TESTS */
|
||||
/***EOF***/
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "sha2.h"
|
||||
#include "sha3.h"
|
||||
|
||||
/* Size calculation macros
|
||||
*/
|
||||
@ -49,6 +50,10 @@ void sha384(unsigned char* out, unsigned char* in, size_t size);
|
||||
void sha384_base64(char* out, unsigned char* in, size_t size);
|
||||
void sha512(unsigned char* out, unsigned char* in, size_t size);
|
||||
void sha512_base64(char* out, unsigned char* in, size_t size);
|
||||
void sha3_256(unsigned char* out, unsigned char* in, size_t size);
|
||||
void sha3_256_base64(char* out, unsigned char* in, size_t size);
|
||||
void sha3_512(unsigned char* out, unsigned char* in, size_t size);
|
||||
void sha3_512_base64(char* out, unsigned char* in, size_t size);
|
||||
|
||||
#endif /* DIGEST_H */
|
||||
|
||||
|
||||
@ -87,6 +87,8 @@ typedef enum {
|
||||
FKO_DIGEST_SHA256, /**< SHA256 digest type*/
|
||||
FKO_DIGEST_SHA384, /**< SHA384 digest type*/
|
||||
FKO_DIGEST_SHA512, /**< SHA512 digest type*/
|
||||
FKO_DIGEST_SHA3_256, /**< SHA3 256 digest type*/
|
||||
FKO_DIGEST_SHA3_512, /**< SHA3 512 digest type*/
|
||||
FKO_LAST_DIGEST_TYPE /**< Always leave this as the last one */
|
||||
} fko_digest_type_t;
|
||||
|
||||
@ -104,6 +106,8 @@ typedef enum {
|
||||
FKO_HMAC_SHA256, /**< SHA256 HMAC type*/
|
||||
FKO_HMAC_SHA384, /**< SHA384 HMAC type*/
|
||||
FKO_HMAC_SHA512, /**< SHA512 HMAC type*/
|
||||
FKO_HMAC_SHA3_256, /**< SHA3 256 HMAC type */
|
||||
FKO_HMAC_SHA3_512, /**< SHA3 512 HMAC type*/
|
||||
FKO_LAST_HMAC_MODE /**< Always leave this as the last one */
|
||||
} fko_hmac_type_t;
|
||||
|
||||
@ -1394,6 +1398,10 @@ DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char * const fpr,
|
||||
|
||||
#ifdef HAVE_C_UNIT_TESTS
|
||||
int register_ts_fko_decode(void);
|
||||
int register_ts_hmac_test(void);
|
||||
int register_ts_digest_test(void);
|
||||
int register_ts_aes_test(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* FKO_H */
|
||||
|
||||
@ -193,6 +193,26 @@ set_digest(char *data, char **digest, short digest_type, int *digest_len)
|
||||
*digest_len = SHA512_B64_LEN;
|
||||
break;
|
||||
|
||||
case FKO_DIGEST_SHA3_256:
|
||||
md = calloc(1, MD_HEX_SIZE(SHA3_256_DIGEST_LEN)+1);
|
||||
if(md == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
sha3_256_base64(md,
|
||||
(unsigned char*)data, data_len);
|
||||
*digest_len = SHA3_256_B64_LEN;
|
||||
break;
|
||||
|
||||
case FKO_DIGEST_SHA3_512:
|
||||
md = calloc(1, MD_HEX_SIZE(SHA3_512_DIGEST_LEN)+1);
|
||||
if(md == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
sha3_512_base64(md,
|
||||
(unsigned char*)data, data_len);
|
||||
*digest_len = SHA3_512_B64_LEN;
|
||||
break;
|
||||
|
||||
default:
|
||||
return(FKO_ERROR_INVALID_DIGEST_TYPE);
|
||||
}
|
||||
|
||||
@ -67,6 +67,10 @@ fko_verify_hmac(fko_ctx_t ctx,
|
||||
hmac_b64_digest_len = SHA384_B64_LEN;
|
||||
else if(ctx->hmac_type == FKO_HMAC_SHA512)
|
||||
hmac_b64_digest_len = SHA512_B64_LEN;
|
||||
else if(ctx->hmac_type == FKO_HMAC_SHA3_256)
|
||||
hmac_b64_digest_len = SHA3_256_B64_LEN;
|
||||
else if(ctx->hmac_type == FKO_HMAC_SHA3_512)
|
||||
hmac_b64_digest_len = SHA3_512_B64_LEN;
|
||||
else
|
||||
return(FKO_ERROR_UNSUPPORTED_HMAC_MODE);
|
||||
|
||||
@ -289,6 +293,22 @@ int fko_set_spa_hmac(fko_ctx_t ctx,
|
||||
hmac_digest_len = SHA512_DIGEST_LEN;
|
||||
hmac_digest_str_len = SHA512_DIGEST_STR_LEN;
|
||||
}
|
||||
else if(ctx->hmac_type == FKO_HMAC_SHA3_256)
|
||||
{
|
||||
hmac_sha3_256(ctx->encrypted_msg,
|
||||
ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
|
||||
hmac_digest_len = SHA3_256_DIGEST_LEN;
|
||||
hmac_digest_str_len = SHA3_256_DIGEST_STR_LEN;
|
||||
|
||||
}
|
||||
else if(ctx->hmac_type == FKO_HMAC_SHA3_512)
|
||||
{
|
||||
hmac_sha3_512(ctx->encrypted_msg,
|
||||
ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
|
||||
hmac_digest_len = SHA3_512_DIGEST_LEN;
|
||||
hmac_digest_str_len = SHA3_512_DIGEST_STR_LEN;
|
||||
|
||||
}
|
||||
|
||||
hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1);
|
||||
if (hmac_base64 == NULL)
|
||||
|
||||
@ -4,13 +4,16 @@
|
||||
|
||||
/**
|
||||
* Register test suites from FKO files.
|
||||
*
|
||||
*
|
||||
* The module should fetch functions according to used modules. All of them follow the same
|
||||
* naming convention.
|
||||
*/
|
||||
static void register_test_suites(void)
|
||||
{
|
||||
register_ts_fko_decode();
|
||||
register_ts_hmac_test();
|
||||
register_ts_digest_test();
|
||||
register_ts_aes_test();
|
||||
}
|
||||
|
||||
/* The main() function for setting up and running the tests.
|
||||
|
||||
1210
lib/hmac.c
1210
lib/hmac.c
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@
|
||||
|
||||
#include "digest.h"
|
||||
|
||||
#define MAX_DIGEST_BLOCK_LEN SHA512_BLOCK_LEN
|
||||
#define MAX_DIGEST_BLOCK_LEN SHA3_256_BLOCK_LEN
|
||||
/**
|
||||
* \brief Generate MD5 based HMAC
|
||||
*
|
||||
@ -56,6 +56,10 @@ void hmac_sha384(const char *msg, const unsigned int msg_len,
|
||||
unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
|
||||
void hmac_sha512(const char *msg, const unsigned int msg_len,
|
||||
unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
|
||||
void hmac_sha3_256(const char *msg, const unsigned int msg_len,
|
||||
unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
|
||||
void hmac_sha3_512(const char *msg, const unsigned int msg_len,
|
||||
unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
|
||||
|
||||
#endif /* HMAC_H */
|
||||
|
||||
|
||||
334
lib/sha3.c
Normal file
334
lib/sha3.c
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
|
||||
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
|
||||
denoted as "the implementer".
|
||||
|
||||
For more information, feedback or questions, please refer to our websites:
|
||||
http://keccak.noekeon.org/
|
||||
http://keyak.noekeon.org/
|
||||
http://ketje.noekeon.org/
|
||||
|
||||
To the extent possible under law, the implementer has waived all copyright
|
||||
and related or neighboring rights to the source code in this file.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/*
|
||||
================================================================
|
||||
The purpose of this source file is to demonstrate a readable and compact
|
||||
implementation of all the Keccak instances approved in the FIPS 202 standard,
|
||||
including the hash functions and the extendable-output functions (XOFs).
|
||||
|
||||
We focused on clarity and on source-code compactness,
|
||||
rather than on the performance.
|
||||
|
||||
The advantages of this implementation are:
|
||||
+ The source code is compact, after removing the comments, that is. :-)
|
||||
+ There are no tables with arbitrary constants.
|
||||
+ For clarity, the comments link the operations to the specifications using
|
||||
the same notation as much as possible.
|
||||
+ There is no restriction in cryptographic features. In particular,
|
||||
the SHAKE128 and SHAKE256 XOFs can produce any output length.
|
||||
+ The code does not use much RAM, as all operations are done in place.
|
||||
|
||||
The drawbacks of this implementation are:
|
||||
- There is no message queue. The whole message must be ready in a buffer.
|
||||
- It is not optimized for peformance.
|
||||
|
||||
The implementation is even simpler on a little endian platform. Just define the
|
||||
LITTLE_ENDIAN symbol in that case.
|
||||
|
||||
For a more complete set of implementations, please refer to
|
||||
the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage
|
||||
|
||||
For more information, please refer to:
|
||||
* [Keccak Reference] http://keccak.noekeon.org/Keccak-reference-3.0.pdf
|
||||
* [Keccak Specifications Summary] http://keccak.noekeon.org/specs_summary.html
|
||||
|
||||
This file uses UTF-8 encoding, as some comments use Greek letters.
|
||||
================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to compute the Keccak[r, c] sponge function over a given input.
|
||||
* @param rate The value of the rate r.
|
||||
* @param capacity The value of the capacity c.
|
||||
* @param input Pointer to the input message.
|
||||
* @param inputByteLen The number of input bytes provided in the input message.
|
||||
* @param delimitedSuffix Bits that will be automatically appended to the end
|
||||
* of the input message, as in domain separation.
|
||||
* This is a byte containing from 0 to 7 bits
|
||||
* These <i>n</i> bits must be in the least significant bit positions
|
||||
* and must be delimited with a bit 1 at position <i>n</i>
|
||||
* (counting from 0=LSB to 7=MSB) and followed by bits 0
|
||||
* from position <i>n</i>+1 to position 7.
|
||||
* Some examples:
|
||||
* - If no bits are to be appended, then @a delimitedSuffix must be 0x01.
|
||||
* - If the 2-bit sequence 0,1 is to be appended (as for SHA3-*), @a delimitedSuffix must be 0x06.
|
||||
* - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*), @a delimitedSuffix must be 0x1F.
|
||||
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedSuffix must be 0x8B.
|
||||
* @param output Pointer to the buffer where to store the output.
|
||||
* @param outputByteLen The number of output bytes desired.
|
||||
* @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
|
||||
*/
|
||||
//void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen);
|
||||
|
||||
/**
|
||||
* Function to compute SHAKE128 on the input message with any output length.
|
||||
*/
|
||||
#include "sha3.h"
|
||||
void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
|
||||
{
|
||||
Keccak(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute SHAKE256 on the input message with any output length.
|
||||
*/
|
||||
void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
|
||||
{
|
||||
Keccak(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||
{
|
||||
Keccak(1152, 448, input, inputByteLen, 0x06, output, 28);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||
{
|
||||
Keccak(1088, 512, input, inputByteLen, 0x06, output, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||
{
|
||||
Keccak(832, 768, input, inputByteLen, 0x06, output, 48);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||
{
|
||||
Keccak(576, 1024, input, inputByteLen, 0x06, output, 64);
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================
|
||||
Technicalities
|
||||
================================================================
|
||||
*/
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned long long int UINT64;
|
||||
typedef UINT64 tKeccakLane;
|
||||
|
||||
#ifndef LITTLE_ENDIAN
|
||||
/** Function to load a 64-bit value using the little-endian (LE) convention.
|
||||
* On a LE platform, this could be greatly simplified using a cast.
|
||||
*/
|
||||
static UINT64 load64(const UINT8 *x)
|
||||
{
|
||||
int i;
|
||||
UINT64 u=0;
|
||||
|
||||
for(i=7; i>=0; --i) {
|
||||
u <<= 8;
|
||||
u |= x[i];
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
/** Function to store a 64-bit value using the little-endian (LE) convention.
|
||||
* On a LE platform, this could be greatly simplified using a cast.
|
||||
*/
|
||||
static void store64(UINT8 *x, UINT64 u)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i=0; i<8; ++i) {
|
||||
x[i] = u;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/** Function to XOR into a 64-bit value using the little-endian (LE) convention.
|
||||
* On a LE platform, this could be greatly simplified using a cast.
|
||||
*/
|
||||
static void xor64(UINT8 *x, UINT64 u)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i=0; i<8; ++i) {
|
||||
x[i] ^= u;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================================================================
|
||||
A readable and compact implementation of the Keccak-f[1600] permutation.
|
||||
================================================================
|
||||
*/
|
||||
|
||||
#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset)))
|
||||
#define i(x, y) ((x)+5*(y))
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#define readLane(x, y) (((tKeccakLane*)state)[i(x, y)])
|
||||
#define writeLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) = (lane)
|
||||
#define XORLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) ^= (lane)
|
||||
#else
|
||||
#define readLane(x, y) load64((UINT8*)state+sizeof(tKeccakLane)*i(x, y))
|
||||
#define writeLane(x, y, lane) store64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane)
|
||||
#define XORLane(x, y, lane) xor64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function that computes the linear feedback shift register (LFSR) used to
|
||||
* define the round constants (see [Keccak Reference, Section 1.2]).
|
||||
*/
|
||||
int LFSR86540(UINT8 *LFSR)
|
||||
{
|
||||
int result = ((*LFSR) & 0x01) != 0;
|
||||
if (((*LFSR) & 0x80) != 0)
|
||||
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
|
||||
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
|
||||
else
|
||||
(*LFSR) <<= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that computes the Keccak-f[1600] permutation on the given state.
|
||||
*/
|
||||
void KeccakF1600_StatePermute(void *state)
|
||||
{
|
||||
unsigned int round, x, y, j, t;
|
||||
UINT8 LFSRstate = 0x01;
|
||||
|
||||
for(round=0; round<24; round++) {
|
||||
{ // === θ step (see [Keccak Reference, Section 2.3.2]) ===
|
||||
tKeccakLane C[5], D;
|
||||
|
||||
// Compute the parity of the columns
|
||||
for(x=0; x<5; x++)
|
||||
C[x] = readLane(x, 0) ^ readLane(x, 1) ^ readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4);
|
||||
for(x=0; x<5; x++) {
|
||||
// Compute the θ effect for a given column
|
||||
D = C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1);
|
||||
// Add the θ effect to the whole column
|
||||
for (y=0; y<5; y++)
|
||||
XORLane(x, y, D);
|
||||
}
|
||||
}
|
||||
|
||||
{ // === ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) ===
|
||||
tKeccakLane current, temp;
|
||||
// Start at coordinates (1 0)
|
||||
x = 1; y = 0;
|
||||
current = readLane(x, y);
|
||||
// Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23
|
||||
for(t=0; t<24; t++) {
|
||||
// Compute the rotation constant r = (t+1)(t+2)/2
|
||||
unsigned int r = ((t+1)*(t+2)/2)%64;
|
||||
// Compute ((0 1)(2 3)) * (x y)
|
||||
unsigned int Y = (2*x+3*y)%5; x = y; y = Y;
|
||||
// Swap current and state(x,y), and rotate
|
||||
temp = readLane(x, y);
|
||||
writeLane(x, y, ROL64(current, r));
|
||||
current = temp;
|
||||
}
|
||||
}
|
||||
|
||||
{ // === χ step (see [Keccak Reference, Section 2.3.1]) ===
|
||||
tKeccakLane temp[5];
|
||||
for(y=0; y<5; y++) {
|
||||
// Take a copy of the plane
|
||||
for(x=0; x<5; x++)
|
||||
temp[x] = readLane(x, y);
|
||||
// Compute χ on the plane
|
||||
for(x=0; x<5; x++)
|
||||
writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]));
|
||||
}
|
||||
}
|
||||
|
||||
{ // === ι step (see [Keccak Reference, Section 2.3.5]) ===
|
||||
for(j=0; j<7; j++) {
|
||||
unsigned int bitPosition = (1<<j)-1; //2^j-1
|
||||
if (LFSR86540(&LFSRstate))
|
||||
XORLane(0, 0, (tKeccakLane)1<<bitPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================
|
||||
A readable and compact implementation of the Keccak sponge functions
|
||||
that use the Keccak-f[1600] permutation.
|
||||
================================================================
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen)
|
||||
{
|
||||
UINT8 state[200];
|
||||
unsigned int rateInBytes = rate/8;
|
||||
unsigned int blockSize = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (((rate + capacity) != 1600) || ((rate % 8) != 0))
|
||||
return;
|
||||
|
||||
// === Initialize the state ===
|
||||
memset(state, 0, sizeof(state));
|
||||
|
||||
// === Absorb all the input blocks ===
|
||||
while(inputByteLen > 0) {
|
||||
blockSize = MIN(inputByteLen, rateInBytes);
|
||||
for(i=0; i<blockSize; i++)
|
||||
state[i] ^= input[i];
|
||||
input += blockSize;
|
||||
inputByteLen -= blockSize;
|
||||
|
||||
if (blockSize == rateInBytes) {
|
||||
KeccakF1600_StatePermute(state);
|
||||
blockSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// === Do the padding and switch to the squeezing phase ===
|
||||
// Absorb the last few bits and add the first bit of padding (which coincides with the delimiter in delimitedSuffix)
|
||||
state[blockSize] ^= delimitedSuffix;
|
||||
// If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding
|
||||
if (((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes-1)))
|
||||
KeccakF1600_StatePermute(state);
|
||||
// Add the second bit of padding
|
||||
state[rateInBytes-1] ^= 0x80;
|
||||
// Switch to the squeezing phase
|
||||
KeccakF1600_StatePermute(state);
|
||||
|
||||
// === Squeeze out all the output blocks ===
|
||||
while(outputByteLen > 0) {
|
||||
blockSize = MIN(outputByteLen, rateInBytes);
|
||||
memcpy(output, state, blockSize);
|
||||
output += blockSize;
|
||||
outputByteLen -= blockSize;
|
||||
|
||||
if (outputByteLen > 0)
|
||||
KeccakF1600_StatePermute(state);
|
||||
}
|
||||
}
|
||||
40
lib/sha3.h
Normal file
40
lib/sha3.h
Normal file
@ -0,0 +1,40 @@
|
||||
#define SHA3_256_DIGEST_LEN 32
|
||||
#define SHA3_512_DIGEST_LEN 64
|
||||
#define SHA3_256_BLOCK_LEN 136
|
||||
#define SHA3_512_BLOCK_LEN 72
|
||||
#define SHA3_256_B64_LEN 43
|
||||
#define SHA3_512_B64_LEN 86
|
||||
#define SHA3_256_DIGEST_STR_LEN (SHA3_256_DIGEST_LEN * 2 + 1)
|
||||
#define SHA3_512_DIGEST_STR_LEN (SHA3_512_DIGEST_LEN * 2 + 1)
|
||||
|
||||
void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen);
|
||||
|
||||
/**
|
||||
* Function to compute SHAKE128 on the input message with any output length.
|
||||
*/
|
||||
void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen);
|
||||
|
||||
/**
|
||||
* Function to compute SHAKE256 on the input message with any output length.
|
||||
*/
|
||||
void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen);
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output);
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output);
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output);
|
||||
|
||||
/**
|
||||
* Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes.
|
||||
*/
|
||||
void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output);
|
||||
@ -1638,7 +1638,7 @@ parse_access_file(fko_srv_options_t *opts, char *access_filename, int *depth)
|
||||
if(curr_acc->hmac_type < 0)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"[*] HMAC_DIGEST_TYPE argument '%s' must be one of {md5,sha1,sha256,sha384,sha512}",
|
||||
"[*] HMAC_DIGEST_TYPE argument '%s' must be one of {md5,sha1,sha256,sha384,sha512,sha3_256,sha3_512}",
|
||||
val);
|
||||
fclose(file_ptr);
|
||||
return EXIT_FAILURE;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user