diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-10-27 11:18:40 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-10-27 11:18:40 +0000 |
commit | 9f25f5d50ea7c3366e6791f69cc8ea6bfc0dddbd (patch) | |
tree | 12af322ff4e007a3ca79189b0b0d9f367c906dcf /src/libcryptobox | |
parent | d8688b6d2c58241328149aedbd998ddca6591b9f (diff) | |
download | rspamd-9f25f5d50ea7c3366e6791f69cc8ea6bfc0dddbd.tar.gz rspamd-9f25f5d50ea7c3366e6791f69cc8ea6bfc0dddbd.zip |
Fix critical issue in keyed blake2 implementation.
Diffstat (limited to 'src/libcryptobox')
-rw-r--r-- | src/libcryptobox/blake2/blake2.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/libcryptobox/blake2/blake2.c b/src/libcryptobox/blake2/blake2.c index 594459bf7..addaf61f5 100644 --- a/src/libcryptobox/blake2/blake2.c +++ b/src/libcryptobox/blake2/blake2.c @@ -139,12 +139,31 @@ blake2b_init (blake2b_state *S) void blake2b_keyed_init (blake2b_state *S, const unsigned char *key, size_t keylen) { - unsigned char k[BLAKE2B_BLOCKBYTES] = {0}; + unsigned char k[BLAKE2B_BLOCKBYTES]; + blake2b_state _ks; + blake2b_state_internal *state = (blake2b_state_internal *)S; - g_assert (keylen <= BLAKE2B_KEYBYTES); - memcpy (k, key, keylen); - blake2b_init (S); - blake2b_update (S, k, BLAKE2B_BLOCKBYTES); + memset (k, 0, sizeof (k)); + + if (keylen <= BLAKE2B_KEYBYTES) { + memcpy (k, key, keylen); + blake2b_init (S); + state->h[1] ^= keylen; + blake2b_update (S, k, sizeof (k)); + } + else { + blake2b_init (S); + /* + * We use additional blake2 iteration to store large key + * XXX: it is not compatible with the original implementation but safe + */ + blake2b_init (&_ks); + blake2b_update (&_ks, key, keylen); + blake2b_final (&_ks, k); + blake2b_keyed_init (S, k, BLAKE2B_KEYBYTES); + } + + rspamd_explicit_memzero (k, sizeof (k)); } /* hash inlen bytes from in, which may or may not be word aligned, returns the number of bytes used */ |