From a586df583a9ecd1387c3f7850f61b20ab41f05a3 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 5 Nov 2013 21:00:04 -0800 Subject: [PATCH 1/4] Use blake2b_init() *or* blake2b_init_key(). Calling both is not needed. --- .../blake2/ref/generichash_blake2b.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c b/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c index 8329ba38..5ef9d406 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c +++ b/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c @@ -33,11 +33,11 @@ crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, } assert(outlen <= UINT8_MAX); assert(keylen <= UINT8_MAX); - if (blake2b_init(state, (uint8_t) outlen) != 0) { - return -1; - } - if (key != NULL && keylen > 0U && - blake2b_init_key(state, (uint8_t) outlen, key, keylen) != 0) { + if (key == NULL || keylen <= 0U) { + if (blake2b_init(state, (uint8_t) outlen) != 0) { + return -1; + } + } else if (blake2b_init_key(state, (uint8_t) outlen, key, keylen) != 0) { return -1; } return 0; From e9c46aef5f5ea207c41675aeb5e92df284b0312a Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 5 Nov 2013 21:46:19 -0800 Subject: [PATCH 2/4] Add support for salt & personalization to Blake2. This API might change. I'm not a big fan of what we have now. --- .../blake2/generichash_blake2_api.c | 10 +++ .../crypto_generichash/blake2/ref/blake2.h | 18 +++-- .../blake2/ref/blake2b-ref.c | 69 +++++++++++++++++++ .../blake2/ref/generichash_blake2b.c | 26 +++++++ .../sodium/crypto_generichash_blake2b.h | 15 ++++ 5 files changed, 132 insertions(+), 6 deletions(-) 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, From 6745db7a0b3f4b8054fa129590794ed07a0d34bc Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 5 Nov 2013 22:28:33 -0800 Subject: [PATCH 3/4] Add blake2b_salt_personal() --- .../crypto_generichash/blake2/ref/blake2.h | 2 ++ .../blake2/ref/blake2b-ref.c | 28 ++++++++++++++++++- .../blake2/ref/generichash_blake2b.c | 19 +++++++++++++ .../sodium/crypto_generichash_blake2b.h | 9 ++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2.h b/src/libsodium/crypto_generichash/blake2/ref/blake2.h index 428f9478..8ed5301a 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2.h +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2.h @@ -27,6 +27,7 @@ #define blake2b_update crypto_generichash_blake2b__update #define blake2b_final crypto_generichash_blake2b__final #define blake2b crypto_generichash_blake2b__blake2b +#define blake2b_salt_personal crypto_generichash_blake2b__blake2b_salt_personal #if defined(_MSC_VER) #define ALIGN(x) __declspec(align(x)) @@ -158,6 +159,7 @@ typedef crypto_generichash_blake2b_state blake2b_state; // Simple API int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + int blake2b_salt_personal( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen, const void *salt, const void *personal ); int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c index db5be864..b798c486 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c @@ -185,7 +185,7 @@ int blake2b_init( blake2b_state *S, const uint8_t outlen ) } int blake2b_init_salt_personal( blake2b_state *S, const uint8_t outlen, - const void *salt, const void *personal) + const void *salt, const void *personal ) { blake2b_param P[1]; @@ -431,3 +431,29 @@ int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen blake2b_final( S, out, outlen ); return 0; } + +int blake2b_salt_personal( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen, + const void *salt, const void *personal ) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key ) keylen = 0; + + if( keylen > 0 ) + { + if( blake2b_init_key_salt_personal( S, outlen, key, keylen, salt, personal ) < 0 ) return -1; + } + else + { + if( blake2b_init_salt_personal( S, outlen, salt, personal ) < 0 ) return -1; + } + + blake2b_update( S, ( const uint8_t * )in, inlen ); + blake2b_final( S, out, outlen ); + return 0; +} diff --git a/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c b/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c index f0c98cd8..d6cb4030 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c +++ b/src/libsodium/crypto_generichash/blake2/ref/generichash_blake2b.c @@ -22,6 +22,25 @@ crypto_generichash_blake2b(unsigned char *out, size_t outlen, (uint8_t) outlen, (uint64_t) inlen, (uint8_t) keylen); } +int +crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, size_t keylen, + const unsigned char *salt, + const unsigned char *personal) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + + return blake2b_salt_personal((uint8_t *) out, in, key, + (uint8_t) outlen, (uint64_t) inlen, (uint8_t) keylen, + salt, personal); +} + int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, const unsigned char *key, diff --git a/src/libsodium/include/sodium/crypto_generichash_blake2b.h b/src/libsodium/include/sodium/crypto_generichash_blake2b.h index d1705225..24829d4b 100644 --- a/src/libsodium/include/sodium/crypto_generichash_blake2b.h +++ b/src/libsodium/include/sodium/crypto_generichash_blake2b.h @@ -68,6 +68,15 @@ int crypto_generichash_blake2b(unsigned char *out, size_t outlen, unsigned long long inlen, const unsigned char *key, size_t keylen); +SODIUM_EXPORT +int crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, + size_t keylen, + const unsigned char *salt, + const unsigned char *personal); + SODIUM_EXPORT int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, const unsigned char *key, From 1f405ef7f243201964e55aeaafe32c81b89f07b6 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 5 Nov 2013 22:30:39 -0800 Subject: [PATCH 4/4] void * casts for c++ compat --- src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c index b798c486..1ae6b926 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c @@ -201,12 +201,12 @@ int blake2b_init_salt_personal( blake2b_state *S, const uint8_t outlen, P->inner_length = 0; memset( P->reserved, 0, sizeof( P->reserved ) ); if (salt != NULL) { - blake2b_param_set_salt( P, salt ); + blake2b_param_set_salt( P, (const uint8_t *) salt ); } else { memset( P->salt, 0, sizeof( P->salt ) ); } if (personal != NULL) { - blake2b_param_set_personal( P, personal ); + blake2b_param_set_personal( P, (const uint8_t *) personal ); } else { memset( P->personal, 0, sizeof( P->personal ) ); } @@ -264,12 +264,12 @@ int blake2b_init_key_salt_personal( blake2b_state *S, const uint8_t outlen, cons P->inner_length = 0; memset( P->reserved, 0, sizeof( P->reserved ) ); if (salt != NULL) { - blake2b_param_set_salt( P, salt ); + blake2b_param_set_salt( P, (const uint8_t *) salt ); } else { memset( P->salt, 0, sizeof( P->salt ) ); } if (personal != NULL) { - blake2b_param_set_personal( P, personal ); + blake2b_param_set_personal( P, (const uint8_t *) personal ); } else { memset( P->personal, 0, sizeof( P->personal ) ); }