diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index c11890b2..13aee214 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -36,6 +36,7 @@ libsodium_la_SOURCES = \ crypto_generichash/blake2/ref/api.h \ crypto_generichash/blake2/ref/blake2-impl.h \ crypto_generichash/blake2/ref/blake2.h \ + crypto_generichash/blake2/ref/blake2b-compress-ref.c \ crypto_generichash/blake2/ref/blake2b-load-sse2.h \ crypto_generichash/blake2/ref/blake2b-load-sse41.h \ crypto_generichash/blake2/ref/blake2b-ref.c \ diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2.h b/src/libsodium/crypto_generichash/blake2/ref/blake2.h index 85e00847..f8fc6a8e 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2.h +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2.h @@ -179,6 +179,8 @@ typedef crypto_generichash_blake2b_state blake2b_state; return blake2b( out, in, key, outlen, inlen, keylen ); } + typedef int ( *blake2b_compress_fn )( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ); + int blake2b_compress_ref( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ); int blake2b_compress_ssse3( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ); int blake2b_compress_sse41( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ); diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ref.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ref.c new file mode 100644 index 00000000..ce9d1d4c --- /dev/null +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ref.c @@ -0,0 +1,95 @@ + +#define BLAKE2_USE_SSSE2 + +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + +int blake2b_compress_ref( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; + int i; + + for( i = 0; i < 16; ++i ) + m[i] = load64( block + i * sizeof( m[i] ) ); + + for( i = 0; i < 8; ++i ) + v[i] = S->h[i]; + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = S->t[0] ^ blake2b_IV[4]; + v[13] = S->t[1] ^ blake2b_IV[5]; + v[14] = S->f[0] ^ blake2b_IV[6]; + v[15] = S->f[1] ^ blake2b_IV[7]; +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + +#undef G +#undef ROUND + return 0; +} diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-sse41.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-sse41.c index 4ce1abcc..11e38b11 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-sse41.c +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-sse41.c @@ -3,7 +3,6 @@ #define BLAKE2_USE_SSE41 #include -#include #include #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ssse3.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ssse3.c index 78cc70ff..1ac1832e 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ssse3.c +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-compress-ssse3.c @@ -2,7 +2,6 @@ #define BLAKE2_USE_SSSE2 #include -#include #include #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c index 96ebc9c4..2e511da5 100644 --- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c +++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c @@ -17,6 +17,7 @@ #include "blake2.h" #include "blake2-impl.h" +#include "runtime.h" static const uint64_t blake2b_IV[8] = { @@ -26,23 +27,6 @@ static const uint64_t blake2b_IV[8] = 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; -static const uint8_t blake2b_sigma[12][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - - /* LCOV_EXCL_START */ static inline int blake2b_set_lastnode( blake2b_state *S ) { @@ -292,72 +276,18 @@ int blake2b_init_key_salt_personal( blake2b_state *S, const uint8_t outlen, cons return 0; } -static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) -{ - uint64_t m[16]; - uint64_t v[16]; - int i; - - for( i = 0; i < 16; ++i ) - m[i] = load64( block + i * sizeof( m[i] ) ); - - for( i = 0; i < 8; ++i ) - v[i] = S->h[i]; - - v[ 8] = blake2b_IV[0]; - v[ 9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = S->t[0] ^ blake2b_IV[4]; - v[13] = S->t[1] ^ blake2b_IV[5]; - v[14] = S->f[0] ^ blake2b_IV[6]; - v[15] = S->f[1] ^ blake2b_IV[7]; -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2*i+0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2*i+1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while(0) -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - - for( i = 0; i < 8; ++i ) - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - -#undef G -#undef ROUND - return 0; -} - /* inlen now in bytes */ int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) { + blake2b_compress_fn blake2b_compress; + + if (sodium_runtime_has_sse41()) { + blake2b_compress = blake2b_compress_sse41; + } else if (sodium_runtime_has_ssse3()) { + blake2b_compress = blake2b_compress_ssse3; + } else { + blake2b_compress = blake2b_compress_ref; + } while( inlen > 0 ) { size_t left = S->buflen; @@ -388,9 +318,18 @@ 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 ) { + blake2b_compress_fn blake2b_compress; + if( !outlen || outlen > BLAKE2B_OUTBYTES ) { return -1; } + if (sodium_runtime_has_sse41()) { + blake2b_compress = blake2b_compress_sse41; + } else if (sodium_runtime_has_ssse3()) { + blake2b_compress = blake2b_compress_ssse3; + } else { + blake2b_compress = blake2b_compress_ref; + } if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );