diff --git a/src/libsodium/crypto_generichash/blake2/generichash_blake2_api.c b/src/libsodium/crypto_generichash/blake2/generichash_blake2_api.c index c62693f6..70af68e2 100644 --- a/src/libsodium/crypto_generichash/blake2/generichash_blake2_api.c +++ b/src/libsodium/crypto_generichash/blake2/generichash_blake2_api.c @@ -25,6 +25,16 @@ crypto_generichash_blake2b_blockbytes(void) { return crypto_generichash_blake2b_BLOCKBYTES; } +size_t +crypto_generichash_blake2b_salt_bytes(void) { + return crypto_generichash_blake2b_SALTBYTES; +} + +size_t +crypto_generichash_blake2b_personal_bytes(void) { + return crypto_generichash_blake2b_PERSONALBYTES; +} + const char * crypto_generichash_blake2b_blockbytes_primitive(void) { return "blake2b"; diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2.h b/src/libsodium/crypto_generichash/blake2/ref/blake2.h index 81f63c04..428f9478 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2.h +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2.h @@ -19,12 +19,14 @@ #include "crypto_generichash_blake2b.h" -#define blake2b_init_param crypto_generichash_blake2b__init_param -#define blake2b_init crypto_generichash_blake2b__init -#define blake2b_init_key crypto_generichash_blake2b__init_key -#define blake2b_update crypto_generichash_blake2b__update -#define blake2b_final crypto_generichash_blake2b__final -#define blake2b crypto_generichash_blake2b__blake2b +#define blake2b_init_param crypto_generichash_blake2b__init_param +#define blake2b_init crypto_generichash_blake2b__init +#define blake2b_init_salt_personal crypto_generichash_blake2b__init_salt_personal +#define blake2b_init_key crypto_generichash_blake2b__init_key +#define blake2b_init_key_salt_personal crypto_generichash_blake2b__init_key_salt_personal +#define blake2b_update crypto_generichash_blake2b__update +#define blake2b_final crypto_generichash_blake2b__final +#define blake2b crypto_generichash_blake2b__blake2b #if defined(_MSC_VER) #define ALIGN(x) __declspec(align(x)) @@ -134,7 +136,11 @@ typedef crypto_generichash_blake2b_state blake2b_state; int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ); int blake2b_init( blake2b_state *S, const uint8_t outlen ); + int blake2b_init_salt_personal( blake2b_state *S, const uint8_t outlen, + const void *personal, const void *salt ); int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2b_init_key_salt_personal( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen, + const void *salt, const void *personal ); int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ); int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ); diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c index f43bc6bf..db5be864 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c @@ -184,6 +184,34 @@ int blake2b_init( blake2b_state *S, const uint8_t outlen ) return blake2b_init_param( S, P ); } +int blake2b_init_salt_personal( blake2b_state *S, const uint8_t outlen, + const void *salt, const void *personal) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + if (salt != NULL) { + blake2b_param_set_salt( P, salt ); + } else { + memset( P->salt, 0, sizeof( P->salt ) ); + } + if (personal != NULL) { + blake2b_param_set_personal( P, personal ); + } else { + memset( P->personal, 0, sizeof( P->personal ) ); + } + return blake2b_init_param( S, P ); +} int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) { @@ -217,6 +245,47 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c return 0; } +int blake2b_init_key_salt_personal( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen, + const void *salt, const void *personal ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + if (salt != NULL) { + blake2b_param_set_salt( P, salt ); + } else { + memset( P->salt, 0, sizeof( P->salt ) ); + } + if (personal != NULL) { + blake2b_param_set_personal( P, personal ); + } else { + memset( P->personal, 0, sizeof( P->personal ) ); + } + + if( blake2b_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) { uint64_t m[16]; diff --git a/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c b/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c index 5ef9d406..f0c98cd8 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c +++ b/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c @@ -43,6 +43,32 @@ crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, return 0; } +int +crypto_generichash_blake2b_init2(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen, + const unsigned char *salt, + const unsigned char *personal) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + if (key == NULL || keylen <= 0U) { + if (blake2b_init_salt_personal(state, (uint8_t) outlen, + salt, personal) != 0) { + return -1; + } + } else if (blake2b_init_key_salt_personal(state, + (uint8_t) outlen, key, keylen, + salt, personal) != 0) { + return -1; + } + return 0; +} + int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, const unsigned char *in, diff --git a/src/libsodium/include/sodium/crypto_generichash_blake2b.h b/src/libsodium/include/sodium/crypto_generichash_blake2b.h index 108541d1..d1705225 100644 --- a/src/libsodium/include/sodium/crypto_generichash_blake2b.h +++ b/src/libsodium/include/sodium/crypto_generichash_blake2b.h @@ -14,6 +14,8 @@ #define crypto_generichash_blake2b_KEYBYTES_MIN 16U #define crypto_generichash_blake2b_KEYBYTES_MAX 64U #define crypto_generichash_blake2b_BLOCKBYTES 128U +#define crypto_generichash_blake2b_SALTBYTES 16U +#define crypto_generichash_blake2b_PERSONALBYTES 16U #if defined(_MSC_VER) # define CRYPTO_ALIGN(x) __declspec(align(x)) @@ -51,6 +53,12 @@ size_t crypto_generichash_blake2b_keybytes_max(void); SODIUM_EXPORT size_t crypto_generichash_blake2b_blockbytes(void); +SODIUM_EXPORT +size_t crypto_generichash_blake2b_saltbytes(void); + +SODIUM_EXPORT +size_t crypto_generichash_blake2b_personalbytes(void); + SODIUM_EXPORT const char * crypto_generichash_blake2b_blockbytes_primitive(void); @@ -65,6 +73,13 @@ int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, const unsigned char *key, const size_t keylen, const size_t outlen); +SODIUM_EXPORT +int crypto_generichash_blake2b_init2(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen, + const unsigned char *salt, + const unsigned char *personal); + SODIUM_EXPORT int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, const unsigned char *in,