Merge branch 'master' of github.com:jedisct1/libsodium

* 'master' of github.com:jedisct1/libsodium:
  void * casts for c++ compat
  Add blake2b_salt_personal()
  Add support for salt & personalization to Blake2. This API might change. I'm not a big fan of what we have now.
  Use blake2b_init() *or* blake2b_init_key(). Calling both is not needed.
This commit is contained in:
Frank Denis
2013-11-11 08:23:06 -08:00
5 changed files with 191 additions and 9 deletions
@@ -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";
@@ -19,12 +19,15 @@
#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
#define blake2b_salt_personal crypto_generichash_blake2b__blake2b_salt_personal
#if defined(_MSC_VER)
#define ALIGN(x) __declspec(align(x))
@@ -134,7 +137,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 );
@@ -152,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 );
@@ -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, (const uint8_t *) salt );
} else {
memset( P->salt, 0, sizeof( P->salt ) );
}
if (personal != NULL) {
blake2b_param_set_personal( P, (const uint8_t *) 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, (const uint8_t *) salt );
} else {
memset( P->salt, 0, sizeof( P->salt ) );
}
if (personal != NULL) {
blake2b_param_set_personal( P, (const uint8_t *) 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];
@@ -362,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;
}
@@ -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,
@@ -33,11 +52,37 @@ 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) {
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;
}
if (key != NULL && keylen > 0U &&
blake2b_init_key(state, (uint8_t) outlen, key, keylen) != 0) {
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;
@@ -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);
@@ -60,11 +68,27 @@ 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,
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,