Add SHA3 and HMAC-SHA3 support
This commit is contained in:
@@ -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;
|
||||
|
||||
+1
-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
|
||||
|
||||
|
||||
|
||||
@@ -154,4 +154,39 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
/***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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+84
@@ -430,3 +430,87 @@ hmac_sha512(const char *msg, const unsigned int msg_len,
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
hmac_sha3_256(const char *msg, const unsigned int msg_len,
|
||||
unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
|
||||
{
|
||||
unsigned char inner_hash[SHA3_256_DIGEST_LEN] = {0};
|
||||
unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0};
|
||||
unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0};
|
||||
unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0};
|
||||
unsigned char padded_hash[2 * MAX_DIGEST_BLOCK_LEN + 1] = {0};
|
||||
unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1);
|
||||
int final_len = hmac_key_len;
|
||||
|
||||
if(SHA3_256_BLOCK_LEN < hmac_key_len)
|
||||
{
|
||||
/* Calculate the digest of the key
|
||||
*/
|
||||
FIPS202_SHA3_256((unsigned char *)hmac_key, final_len, final_key);
|
||||
final_len = SHA3_256_DIGEST_LEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(final_key, hmac_key, hmac_key_len);
|
||||
}
|
||||
pad_init(block_inner_pad, block_outer_pad, final_key, final_len);
|
||||
//The first step is to hash the inner_pad + message
|
||||
memcpy(padded_msg, block_inner_pad, SHA3_256_BLOCK_LEN);
|
||||
memcpy(padded_msg + SHA3_256_BLOCK_LEN, msg, msg_len);
|
||||
|
||||
//Calculate the inner hash
|
||||
FIPS202_SHA3_256(padded_msg, msg_len + SHA3_256_BLOCK_LEN, inner_hash);
|
||||
|
||||
//Then hash the outer pad + inner hash
|
||||
memcpy(padded_hash, block_outer_pad, SHA3_256_BLOCK_LEN);
|
||||
memcpy(padded_hash + SHA3_256_BLOCK_LEN, inner_hash, SHA3_256_DIGEST_LEN);
|
||||
|
||||
//the outer hash is the final hmac
|
||||
FIPS202_SHA3_256(padded_hash, SHA3_256_BLOCK_LEN + SHA3_256_DIGEST_LEN, hmac);
|
||||
|
||||
free(padded_msg);
|
||||
}
|
||||
|
||||
void
|
||||
hmac_sha3_512(const char *msg, const unsigned int msg_len,
|
||||
unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
|
||||
{
|
||||
unsigned char inner_hash[SHA3_512_DIGEST_LEN] = {0};
|
||||
unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0};
|
||||
unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0};
|
||||
unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0};
|
||||
unsigned char padded_hash[SHA3_512_BLOCK_LEN + SHA3_512_DIGEST_LEN + 1] = {0};
|
||||
unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1);
|
||||
|
||||
int final_len = hmac_key_len;
|
||||
|
||||
if(SHA3_512_BLOCK_LEN < hmac_key_len)
|
||||
{
|
||||
/* Calculate the digest of the key
|
||||
*/
|
||||
FIPS202_SHA3_512((unsigned char *)hmac_key, final_len, final_key);
|
||||
final_len = SHA3_512_DIGEST_LEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(final_key, hmac_key, hmac_key_len);
|
||||
}
|
||||
pad_init(block_inner_pad, block_outer_pad, final_key, final_len);
|
||||
|
||||
//The first step is to hash the inner_pad + message
|
||||
memcpy(padded_msg, block_inner_pad, SHA3_512_BLOCK_LEN);
|
||||
memcpy(padded_msg + SHA3_512_BLOCK_LEN, msg, msg_len);
|
||||
|
||||
//Calculate the inner hash
|
||||
FIPS202_SHA3_512(padded_msg, msg_len + SHA3_512_BLOCK_LEN, inner_hash);
|
||||
|
||||
//Then hash the outer pad + inner hash
|
||||
memcpy(padded_hash, block_outer_pad, SHA3_512_BLOCK_LEN);
|
||||
memcpy(padded_hash + SHA3_512_BLOCK_LEN, inner_hash, SHA3_512_DIGEST_LEN);
|
||||
|
||||
//the outer hash is the final hmac
|
||||
FIPS202_SHA3_512(padded_hash, SHA3_512_BLOCK_LEN + SHA3_512_DIGEST_LEN, hmac);
|
||||
|
||||
free(padded_msg);
|
||||
}
|
||||
|
||||
+5
-1
@@ -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
@@ -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
@@ -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);
|
||||
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user