Adds Blake2s support (--enable-blake2s), which provides 32-bit Blake2 support.

pull/2256/head
David Garske 2019-05-23 21:47:42 -06:00
parent 9906a1045b
commit 5ea13a09f6
12 changed files with 694 additions and 31 deletions

View File

@ -1248,18 +1248,32 @@ AM_CONDITIONAL([BUILD_RIPEMD], [test "x$ENABLED_RIPEMD" = "xyes"])
# BLAKE2 # BLAKE2
AC_ARG_ENABLE([blake2], AC_ARG_ENABLE([blake2],
[AS_HELP_STRING([--enable-blake2],[Enable wolfSSL BLAKE2 support (default: disabled)])], [AS_HELP_STRING([--enable-blake2],[Enable wolfSSL BLAKE2b support (default: disabled)])],
[ ENABLED_BLAKE2=$enableval ], [ ENABLED_BLAKE2=$enableval ],
[ ENABLED_BLAKE2=no ] [ ENABLED_BLAKE2=no ]
) )
if test "$ENABLED_BLAKE2" = "yes" if test "$ENABLED_BLAKE2" = "yes"
then then
AM_CFLAGS="$AM_CFLAGS -DHAVE_BLAKE2" AM_CFLAGS="$AM_CFLAGS -DHAVE_BLAKE2 -DHAVE_BLAKE2B"
fi fi
AM_CONDITIONAL([BUILD_BLAKE2], [test "x$ENABLED_BLAKE2" = "xyes"]) AM_CONDITIONAL([BUILD_BLAKE2], [test "x$ENABLED_BLAKE2" = "xyes"])
AC_ARG_ENABLE([blake2s],
[AS_HELP_STRING([--enable-blake2s],[Enable wolfSSL BLAKE2s support (default: disabled)])],
[ ENABLED_BLAKE2S=$enableval ],
[ ENABLED_BLAKE2S=Sno ]
)
if test "$ENABLED_BLAKE2S" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_BLAKE2S"
ENABLED_BLAKE2="yes"
fi
AM_CONDITIONAL([BUILD_BLAKE2S], [test "x$ENABLED_BLAKE2S" = "xyes"])
# SHA512 # SHA512
AC_ARG_ENABLE([sha512], AC_ARG_ENABLE([sha512],

View File

@ -322,6 +322,9 @@ endif
if BUILD_BLAKE2 if BUILD_BLAKE2
src_libwolfssl_la_SOURCES += wolfcrypt/src/blake2b.c src_libwolfssl_la_SOURCES += wolfcrypt/src/blake2b.c
endif endif
if BUILD_BLAKE2S
src_libwolfssl_la_SOURCES += wolfcrypt/src/blake2s.c
endif
if BUILD_HC128 if BUILD_HC128
src_libwolfssl_la_SOURCES += wolfcrypt/src/hc128.c src_libwolfssl_la_SOURCES += wolfcrypt/src/hc128.c

View File

@ -223,7 +223,9 @@
#define BENCH_SHA3 (BENCH_SHA3_224 | BENCH_SHA3_256 | \ #define BENCH_SHA3 (BENCH_SHA3_224 | BENCH_SHA3_256 | \
BENCH_SHA3_384 | BENCH_SHA3_512) BENCH_SHA3_384 | BENCH_SHA3_512)
#define BENCH_RIPEMD 0x00001000 #define BENCH_RIPEMD 0x00001000
#define BENCH_BLAKE2 0x00002000 #define BENCH_BLAKE2B 0x00002000
#define BENCH_BLAKE2S 0x00004000
/* MAC algorithms. */ /* MAC algorithms. */
#define BENCH_CMAC 0x00000001 #define BENCH_CMAC 0x00000001
#define BENCH_HMAC_MD5 0x00000002 #define BENCH_HMAC_MD5 0x00000002
@ -379,7 +381,10 @@ static const bench_alg bench_digest_opt[] = {
{ "-ripemd", BENCH_RIPEMD }, { "-ripemd", BENCH_RIPEMD },
#endif #endif
#ifdef HAVE_BLAKE2 #ifdef HAVE_BLAKE2
{ "-blake2", BENCH_BLAKE2 }, { "-blake2b", BENCH_BLAKE2B },
#endif
#ifdef HAVE_BLAKE2S
{ "-blake2s", BENCH_BLAKE2S },
#endif #endif
{ NULL, 0} { NULL, 0}
}; };
@ -604,7 +609,7 @@ static const char* bench_desc_words[][9] = {
#include <wolfssl/certs_test.h> #include <wolfssl/certs_test.h>
#endif #endif
#ifdef HAVE_BLAKE2 #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
#include <wolfssl/wolfcrypt/blake2.h> #include <wolfssl/wolfcrypt/blake2.h>
#endif #endif
@ -1454,8 +1459,12 @@ static void* benchmarks_do(void* args)
bench_ripemd(); bench_ripemd();
#endif #endif
#ifdef HAVE_BLAKE2 #ifdef HAVE_BLAKE2
if (bench_all || (bench_digest_algs & BENCH_BLAKE2)) if (bench_all || (bench_digest_algs & BENCH_BLAKE2B))
bench_blake2(); bench_blake2b();
#endif
#ifdef HAVE_BLAKE2S
if (bench_all || (bench_digest_algs & BENCH_BLAKE2S))
bench_blake2s();
#endif #endif
#ifdef WOLFSSL_CMAC #ifdef WOLFSSL_CMAC
if (bench_all || (bench_mac_algs & BENCH_CMAC)) if (bench_all || (bench_mac_algs & BENCH_CMAC))
@ -3589,7 +3598,7 @@ int bench_ripemd(void)
#ifdef HAVE_BLAKE2 #ifdef HAVE_BLAKE2
void bench_blake2(void) void bench_blake2b(void)
{ {
Blake2b b2b; Blake2b b2b;
byte digest[64]; byte digest[64];
@ -3647,6 +3656,65 @@ void bench_blake2(void)
} }
#endif #endif
#if defined(HAVE_BLAKE2S)
void bench_blake2s(void)
{
Blake2s b2s;
byte digest[32];
double start;
int ret = 0, i, count;
if (digest_stream) {
ret = wc_InitBlake2s(&b2s, 32);
if (ret != 0) {
printf("InitBlake2s failed, ret = %d\n", ret);
return;
}
bench_stats_start(&count, &start);
do {
for (i = 0; i < numBlocks; i++) {
ret = wc_Blake2sUpdate(&b2s, bench_plain, BENCH_SIZE);
if (ret != 0) {
printf("Blake2sUpdate failed, ret = %d\n", ret);
return;
}
}
ret = wc_Blake2sFinal(&b2s, digest, 32);
if (ret != 0) {
printf("Blake2sFinal failed, ret = %d\n", ret);
return;
}
count += i;
} while (bench_stats_sym_check(start));
}
else {
bench_stats_start(&count, &start);
do {
for (i = 0; i < numBlocks; i++) {
ret = wc_InitBlake2s(&b2s, 32);
if (ret != 0) {
printf("InitBlake2b failed, ret = %d\n", ret);
return;
}
ret = wc_Blake2sUpdate(&b2s, bench_plain, BENCH_SIZE);
if (ret != 0) {
printf("Blake2bUpdate failed, ret = %d\n", ret);
return;
}
ret = wc_Blake2sFinal(&b2s, digest, 32);
if (ret != 0) {
printf("Blake2sFinal failed, ret = %d\n", ret);
return;
}
}
count += i;
} while (bench_stats_sym_check(start));
}
bench_stats_sym_finish("BLAKE2s", 0, count, bench_size, start, ret);
}
#endif
#ifdef WOLFSSL_CMAC #ifdef WOLFSSL_CMAC

View File

@ -90,7 +90,8 @@ void bench_ed25519KeySign(void);
void bench_ntru(void); void bench_ntru(void);
void bench_ntruKeyGen(void); void bench_ntruKeyGen(void);
void bench_rng(void); void bench_rng(void);
void bench_blake2(void); void bench_blake2b(void);
void bench_blake2s(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,447 @@
/*
BLAKE2 reference source code package - reference C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
/* blake2s.c
*
* Copyright (C) 2006-2019 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#ifdef HAVE_BLAKE2S
#include <wolfssl/wolfcrypt/blake2.h>
#include <wolfssl/wolfcrypt/blake2-impl.h>
static const word32 blake2s_IV[8] =
{
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
static const byte blake2s_sigma[10][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 }
};
static WC_INLINE int blake2s_set_lastnode( blake2s_state *S )
{
S->f[1] = ~0;
return 0;
}
/* Some helper functions, not necessarily useful */
static WC_INLINE int blake2s_set_lastblock( blake2s_state *S )
{
if( S->last_node ) blake2s_set_lastnode( S );
S->f[0] = ~0;
return 0;
}
static WC_INLINE int blake2s_increment_counter( blake2s_state *S, const word32
inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
return 0;
}
static WC_INLINE int blake2s_init0( blake2s_state *S )
{
int i;
XMEMSET( S, 0, sizeof( blake2s_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
return 0;
}
/* init xors IV with input parameter block */
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
{
word32 i;
byte *p ;
blake2s_init0( S );
p = ( byte * )( P );
/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
S->h[i] ^= load32( p + sizeof( S->h[i] ) * i );
return 0;
}
int blake2s_init( blake2s_state *S, const byte outlen )
{
blake2s_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
#ifdef WOLFSSL_BLAKE2S_INIT_EACH_FIELD
P->digest_length = outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
P->node_depth = 0;
P->inner_length = 0;
XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
XMEMSET( P->salt, 0, sizeof( P->salt ) );
XMEMSET( P->personal, 0, sizeof( P->personal ) );
#else
XMEMSET( P, 0, sizeof( *P ) );
P->digest_length = outlen;
P->fanout = 1;
P->depth = 1;
#endif
return blake2s_init_param( S, P );
}
int blake2s_init_key( blake2s_state *S, const byte outlen, const void *key,
const byte keylen )
{
blake2s_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
#ifdef WOLFSSL_BLAKE2S_INIT_EACH_FIELD
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;
XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
XMEMSET( P->salt, 0, sizeof( P->salt ) );
XMEMSET( P->personal, 0, sizeof( P->personal ) );
#else
XMEMSET( P, 0, sizeof( *P ) );
P->digest_length = outlen;
P->key_length = keylen;
P->fanout = 1;
P->depth = 1;
#endif
if( blake2s_init_param( S, P ) < 0 ) return -1;
{
#ifdef WOLFSSL_SMALL_STACK
byte* block;
block = (byte*)XMALLOC(BLAKE2S_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if ( block == NULL ) return -1;
#else
byte block[BLAKE2S_BLOCKBYTES];
#endif
XMEMSET( block, 0, BLAKE2S_BLOCKBYTES );
XMEMCPY( block, key, keylen );
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from */
/* memory */
#ifdef WOLFSSL_SMALL_STACK
XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
}
return 0;
}
static int blake2s_compress( blake2s_state *S,
const byte block[BLAKE2S_BLOCKBYTES] )
{
int i;
#ifdef WOLFSSL_SMALL_STACK
word32* m;
word32* v;
m = (word32*)XMALLOC(sizeof(word32) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if ( m == NULL ) return -1;
v = (word32*)XMALLOC(sizeof(word32) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if ( v == NULL )
{
XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return -1;
}
#else
word32 m[16];
word32 v[16];
#endif
for( i = 0; i < 16; ++i )
m[i] = load32( block + i * sizeof( m[i] ) );
for( i = 0; i < 8; ++i )
v[i] = S->h[i];
v[ 8] = blake2s_IV[0];
v[ 9] = blake2s_IV[1];
v[10] = blake2s_IV[2];
v[11] = blake2s_IV[3];
v[12] = S->t[0] ^ blake2s_IV[4];
v[13] = S->t[1] ^ blake2s_IV[5];
v[14] = S->f[0] ^ blake2s_IV[6];
v[15] = S->f[1] ^ blake2s_IV[7];
#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
d = rotr32(d ^ a, 16); \
c = c + d; \
b = rotr32(b ^ c, 12); \
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
d = rotr32(d ^ a, 8); \
c = c + d; \
b = rotr32(b ^ c, 7); \
} 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 );
for( i = 0; i < 8; ++i )
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
#undef G
#undef ROUND
#ifdef WOLFSSL_SMALL_STACK
XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return 0;
}
/* inlen now in bytes */
int blake2s_update( blake2s_state *S, const byte *in, word32 inlen )
{
while( inlen > 0 )
{
word32 left = S->buflen;
word32 fill = 2 * BLAKE2S_BLOCKBYTES - left;
if( inlen > fill )
{
XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */
S->buflen += fill;
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
if ( blake2s_compress( S, S->buf ) < 0 ) return -1; /* Compress */
XMEMCPY( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
/* Shift buffer left */
S->buflen -= BLAKE2S_BLOCKBYTES;
in += fill;
inlen -= fill;
}
else /* inlen <= fill */
{
XMEMCPY( S->buf + left, in, (wolfssl_word)inlen );
S->buflen += inlen; /* Be lazy, do not compress */
in += inlen;
inlen -= inlen;
}
}
return 0;
}
/* Is this correct? */
int blake2s_final( blake2s_state *S, byte *out, byte outlen )
{
int i;
byte buffer[BLAKE2S_BLOCKBYTES];
if( S->buflen > BLAKE2S_BLOCKBYTES )
{
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
if ( blake2s_compress( S, S->buf ) < 0 ) return -1;
S->buflen -= BLAKE2S_BLOCKBYTES;
XMEMCPY( S->buf, S->buf + BLAKE2S_BLOCKBYTES, (wolfssl_word)S->buflen );
}
blake2s_increment_counter( S, S->buflen );
blake2s_set_lastblock( S );
XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2S_BLOCKBYTES - S->buflen) );
/* Padding */
if ( blake2s_compress( S, S->buf ) < 0 ) return -1;
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
XMEMCPY( out, buffer, outlen );
return 0;
}
/* inlen, at least, should be word32. Others can be size_t. */
int blake2s( byte *out, const void *in, const void *key, const byte outlen,
const word32 inlen, byte keylen )
{
blake2s_state S[1];
/* Verify parameters */
if ( NULL == in ) return -1;
if ( NULL == out ) return -1;
if( NULL == key ) keylen = 0;
if( keylen > 0 )
{
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
}
else
{
if( blake2s_init( S, outlen ) < 0 ) return -1;
}
if ( blake2s_update( S, ( byte * )in, inlen ) < 0) return -1;
return blake2s_final( S, out, outlen );
}
#if defined(BLAKE2S_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
byte key[BLAKE2S_KEYBYTES];
byte buf[KAT_LENGTH];
for( word32 i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( byte )i;
for( word32 i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( byte )i;
for( word32 i = 0; i < KAT_LENGTH; ++i )
{
byte hash[BLAKE2S_OUTBYTES];
if ( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 )
{
puts( "error" );
return -1;
}
if( 0 != XMEMCMP( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}
#endif
/* wolfCrypt API */
/* Init Blake2s digest, track size in case final doesn't want to "remember" */
int wc_InitBlake2s(Blake2s* b2s, word32 digestSz)
{
if (b2s == NULL){
return -1;
}
b2s->digestSz = digestSz;
return blake2s_init(b2s->S, (byte)digestSz);
}
/* Blake2s Update */
int wc_Blake2sUpdate(Blake2s* b2s, const byte* data, word32 sz)
{
return blake2s_update(b2s->S, data, sz);
}
/* Blake2s Final, if pass in zero size we use init digestSz */
int wc_Blake2sFinal(Blake2s* b2s, byte* final, word32 requestSz)
{
word32 sz = requestSz ? requestSz : b2s->digestSz;
return blake2s_final(b2s->S, final, (byte)sz);
}
/* end CTaoCrypt API */
#endif /* HAVE_BLAKE2S */

View File

@ -194,6 +194,7 @@ int wc_HashGetOID(enum wc_HashType hash_type)
/* Not Supported */ /* Not Supported */
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
oid = BAD_FUNC_ARG; oid = BAD_FUNC_ARG;
@ -337,9 +338,14 @@ int wc_HashGetDigestSize(enum wc_HashType hash_type)
dig_size = WC_SHA3_512_DIGEST_SIZE; dig_size = WC_SHA3_512_DIGEST_SIZE;
#endif #endif
break; break;
case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
dig_size = BLAKE2S_OUTBYTES;
#endif
break;
/* Not Supported */ /* Not Supported */
case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
dig_size = BAD_FUNC_ARG; dig_size = BAD_FUNC_ARG;
@ -421,9 +427,14 @@ int wc_HashGetBlockSize(enum wc_HashType hash_type)
block_size = WC_SHA3_512_BLOCK_SIZE; block_size = WC_SHA3_512_BLOCK_SIZE;
#endif #endif
break; break;
case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
block_size = BLAKE2S_BLOCKBYTES;
#endif
break;
/* Not Supported */ /* Not Supported */
case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
block_size = BAD_FUNC_ARG; block_size = BAD_FUNC_ARG;
@ -517,6 +528,7 @@ int wc_Hash(enum wc_HashType hash_type, const byte* data,
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
@ -590,6 +602,7 @@ int wc_HashInit(wc_HashAlg* hash, enum wc_HashType type)
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
@ -664,6 +677,7 @@ int wc_HashUpdate(wc_HashAlg* hash, enum wc_HashType type, const byte* data,
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
@ -737,6 +751,7 @@ int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, byte* out)
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
@ -820,6 +835,7 @@ int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type)
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
@ -882,6 +898,7 @@ int wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type, word32 flags)
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
@ -942,6 +959,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags)
case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD2:
case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD4:
case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2B:
case WC_HASH_TYPE_BLAKE2S:
case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_NONE:
default: default:
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;

View File

@ -160,7 +160,7 @@
#ifdef HAVE_ED25519 #ifdef HAVE_ED25519
#include <wolfssl/wolfcrypt/ed25519.h> #include <wolfssl/wolfcrypt/ed25519.h>
#endif #endif
#ifdef HAVE_BLAKE2 #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
#include <wolfssl/wolfcrypt/blake2.h> #include <wolfssl/wolfcrypt/blake2.h>
#endif #endif
#ifdef WOLFSSL_SHA3 #ifdef WOLFSSL_SHA3
@ -339,6 +339,9 @@ int scrypt_test(void);
#ifdef HAVE_BLAKE2 #ifdef HAVE_BLAKE2
int blake2b_test(void); int blake2b_test(void);
#endif #endif
#ifdef HAVE_BLAKE2S
int blake2s_test(void);
#endif
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
int compress_test(void); int compress_test(void);
#endif #endif
@ -659,6 +662,12 @@ initDefaultName();
else else
test_pass("BLAKE2b test passed!\n"); test_pass("BLAKE2b test passed!\n");
#endif #endif
#ifdef HAVE_BLAKE2S
if ( (ret = blake2s_test()) != 0)
return err_sys("BLAKE2s test failed!\n", ret);
else
test_pass("BLAKE2s test passed!\n");
#endif
#ifndef NO_HMAC #ifndef NO_HMAC
#ifndef NO_MD5 #ifndef NO_MD5
@ -1969,9 +1978,9 @@ int ripemd_test(void)
#ifdef HAVE_BLAKE2 #ifdef HAVE_BLAKE2
#define BLAKE2_TESTS 3 #define BLAKE2B_TESTS 3
static const byte blake2b_vec[BLAKE2_TESTS][BLAKE2B_OUTBYTES] = static const byte blake2b_vec[BLAKE2B_TESTS][BLAKE2B_OUTBYTES] =
{ {
{ {
0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03,
@ -2017,7 +2026,7 @@ int blake2b_test(void)
for (i = 0; i < (int)sizeof(input); i++) for (i = 0; i < (int)sizeof(input); i++)
input[i] = (byte)i; input[i] = (byte)i;
for (i = 0; i < BLAKE2_TESTS; i++) { for (i = 0; i < BLAKE2B_TESTS; i++) {
ret = wc_InitBlake2b(&b2b, 64); ret = wc_InitBlake2b(&b2b, 64);
if (ret != 0) if (ret != 0)
return -2000 - i; return -2000 - i;
@ -2039,6 +2048,67 @@ int blake2b_test(void)
} }
#endif /* HAVE_BLAKE2 */ #endif /* HAVE_BLAKE2 */
#ifdef HAVE_BLAKE2S
#define BLAKE2S_TESTS 3
static const byte blake2s_vec[BLAKE2S_TESTS][BLAKE2S_OUTBYTES] =
{
{
0x69, 0x21, 0x7a, 0x30, 0x79, 0x90, 0x80, 0x94,
0xe1, 0x11, 0x21, 0xd0, 0x42, 0x35, 0x4a, 0x7c,
0x1f, 0x55, 0xb6, 0x48, 0x2c, 0xa1, 0xa5, 0x1e,
0x1b, 0x25, 0x0d, 0xfd, 0x1e, 0xd0, 0xee, 0xf9,
},
{
0xe3, 0x4d, 0x74, 0xdb, 0xaf, 0x4f, 0xf4, 0xc6,
0xab, 0xd8, 0x71, 0xcc, 0x22, 0x04, 0x51, 0xd2,
0xea, 0x26, 0x48, 0x84, 0x6c, 0x77, 0x57, 0xfb,
0xaa, 0xc8, 0x2f, 0xe5, 0x1a, 0xd6, 0x4b, 0xea,
},
{
0xdd, 0xad, 0x9a, 0xb1, 0x5d, 0xac, 0x45, 0x49,
0xba, 0x42, 0xf4, 0x9d, 0x26, 0x24, 0x96, 0xbe,
0xf6, 0xc0, 0xba, 0xe1, 0xdd, 0x34, 0x2a, 0x88,
0x08, 0xf8, 0xea, 0x26, 0x7c, 0x6e, 0x21, 0x0c,
}
};
int blake2s_test(void)
{
Blake2s b2s;
byte digest[32];
byte input[64];
int i, ret;
for (i = 0; i < (int)sizeof(input); i++)
input[i] = (byte)i;
for (i = 0; i < BLAKE2S_TESTS; i++) {
ret = wc_InitBlake2s(&b2s, 32);
if (ret != 0)
return -2000 - i;
ret = wc_Blake2sUpdate(&b2s, input, i);
if (ret != 0)
return -2010 - 1;
ret = wc_Blake2sFinal(&b2s, digest, 32);
if (ret != 0)
return -2020 - i;
if (XMEMCMP(digest, blake2s_vec[i], 32) != 0) {
return -2030 - i;
}
}
return 0;
}
#endif /* HAVE_BLAKE2S */
#ifdef WOLFSSL_SHA224 #ifdef WOLFSSL_SHA224
int sha224_test(void) int sha224_test(void)
@ -3083,11 +3153,21 @@ int hash_test(void)
#endif #endif
ret = wc_HashGetBlockSize(WC_HASH_TYPE_BLAKE2B); ret = wc_HashGetBlockSize(WC_HASH_TYPE_BLAKE2B);
if (ret != BAD_FUNC_ARG) #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG)
return -3091; return -3091;
#else
if (ret != HASH_TYPE_E)
return -3091;
#endif
ret = wc_HashGetDigestSize(WC_HASH_TYPE_BLAKE2B); ret = wc_HashGetDigestSize(WC_HASH_TYPE_BLAKE2B);
if (ret != BAD_FUNC_ARG) #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG)
return -3092; return -3092;
#else
if (ret != HASH_TYPE_E)
return -3092;
#endif
ret = wc_HashGetBlockSize(WC_HASH_TYPE_NONE); ret = wc_HashGetBlockSize(WC_HASH_TYPE_NONE);
if (ret != BAD_FUNC_ARG) if (ret != BAD_FUNC_ARG)

View File

@ -87,13 +87,13 @@
byte personal[BLAKE2S_PERSONALBYTES]; /* 32 */ byte personal[BLAKE2S_PERSONALBYTES]; /* 32 */
} blake2s_param; } blake2s_param;
ALIGN( 64 ) typedef struct __blake2s_state ALIGN( 32 ) typedef struct __blake2s_state
{ {
word32 h[8]; word32 h[8];
word32 t[2]; word32 t[2];
word32 f[2]; word32 f[2];
byte buf[2 * BLAKE2S_BLOCKBYTES]; byte buf[2 * BLAKE2S_BLOCKBYTES];
word64 buflen; word32 buflen;
byte last_node; byte last_node;
} blake2s_state ; } blake2s_state ;
@ -127,7 +127,7 @@
blake2s_state S[8][1]; blake2s_state S[8][1];
blake2s_state R[1]; blake2s_state R[1];
byte buf[8 * BLAKE2S_BLOCKBYTES]; byte buf[8 * BLAKE2S_BLOCKBYTES];
word64 buflen; word32 buflen;
} blake2sp_state; } blake2sp_state;
typedef struct __blake2bp_state typedef struct __blake2bp_state
@ -143,7 +143,7 @@
int blake2s_init( blake2s_state *S, const byte outlen ); int blake2s_init( blake2s_state *S, const byte outlen );
int blake2s_init_key( blake2s_state *S, const byte outlen, const void *key, const byte keylen ); int blake2s_init_key( blake2s_state *S, const byte outlen, const void *key, const byte keylen );
int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
int blake2s_update( blake2s_state *S, const byte *in, word64 inlen ); int blake2s_update( blake2s_state *S, const byte *in, word32 inlen );
int blake2s_final( blake2s_state *S, byte *out, byte outlen ); int blake2s_final( blake2s_state *S, byte *out, byte outlen );
int blake2b_init( blake2b_state *S, const byte outlen ); int blake2b_init( blake2b_state *S, const byte outlen );
@ -154,7 +154,7 @@
int blake2sp_init( blake2sp_state *S, const byte outlen ); int blake2sp_init( blake2sp_state *S, const byte outlen );
int blake2sp_init_key( blake2sp_state *S, const byte outlen, const void *key, const byte keylen ); int blake2sp_init_key( blake2sp_state *S, const byte outlen, const void *key, const byte keylen );
int blake2sp_update( blake2sp_state *S, const byte *in, word64 inlen ); int blake2sp_update( blake2sp_state *S, const byte *in, word32 inlen );
int blake2sp_final( blake2sp_state *S, byte *out, byte outlen ); int blake2sp_final( blake2sp_state *S, byte *out, byte outlen );
int blake2bp_init( blake2bp_state *S, const byte outlen ); int blake2bp_init( blake2bp_state *S, const byte outlen );
@ -163,10 +163,10 @@
int blake2bp_final( blake2bp_state *S, byte *out, byte outlen ); int blake2bp_final( blake2bp_state *S, byte *out, byte outlen );
/* Simple API */ /* Simple API */
int blake2s( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ); int blake2s( byte *out, const void *in, const void *key, const byte outlen, const word32 inlen, byte keylen );
int blake2b( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ); int blake2b( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen );
int blake2sp( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ); int blake2sp( byte *out, const void *in, const void *key, const byte outlen, const word32 inlen, byte keylen );
int blake2bp( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ); int blake2bp( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen );
static WC_INLINE int blake2( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen ) static WC_INLINE int blake2( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen )

View File

@ -28,7 +28,7 @@
#include <wolfssl/wolfcrypt/settings.h> #include <wolfssl/wolfcrypt/settings.h>
#ifdef HAVE_BLAKE2 #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
#include <wolfssl/wolfcrypt/blake2-int.h> #include <wolfssl/wolfcrypt/blake2-int.h>
@ -46,28 +46,51 @@
/* in bytes, variable digest size up to 512 bits (64 bytes) */ /* in bytes, variable digest size up to 512 bits (64 bytes) */
enum { enum {
#ifdef HAVE_BLAKE2B
BLAKE2B_ID = WC_HASH_TYPE_BLAKE2B, BLAKE2B_ID = WC_HASH_TYPE_BLAKE2B,
BLAKE2B_256 = 32 /* 256 bit type, SSL default */ BLAKE2B_256 = 32, /* 256 bit type, SSL default */
#endif
#ifdef HAVE_BLAKE2S
BLAKE2S_ID = WC_HASH_TYPE_BLAKE2S,
BLAKE2S_256 = 32 /* 256 bit type */
#endif
}; };
#ifdef HAVE_BLAKE2B
/* BLAKE2b digest */ /* BLAKE2b digest */
typedef struct Blake2b { typedef struct Blake2b {
blake2b_state S[1]; /* our state */ blake2b_state S[1]; /* our state */
word32 digestSz; /* digest size used on init */ word32 digestSz; /* digest size used on init */
} Blake2b; } Blake2b;
#endif
#ifdef HAVE_BLAKE2S
/* BLAKE2s digest */
typedef struct Blake2s {
blake2s_state S[1]; /* our state */
word32 digestSz; /* digest size used on init */
} Blake2s;
#endif
#ifdef HAVE_BLAKE2B
WOLFSSL_API int wc_InitBlake2b(Blake2b*, word32); WOLFSSL_API int wc_InitBlake2b(Blake2b*, word32);
WOLFSSL_API int wc_Blake2bUpdate(Blake2b*, const byte*, word32); WOLFSSL_API int wc_Blake2bUpdate(Blake2b*, const byte*, word32);
WOLFSSL_API int wc_Blake2bFinal(Blake2b*, byte*, word32); WOLFSSL_API int wc_Blake2bFinal(Blake2b*, byte*, word32);
#endif
#ifdef HAVE_BLAKE2S
WOLFSSL_API int wc_InitBlake2s(Blake2s*, word32);
WOLFSSL_API int wc_Blake2sUpdate(Blake2s*, const byte*, word32);
WOLFSSL_API int wc_Blake2sFinal(Blake2s*, byte*, word32);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* HAVE_BLAKE2 */ #endif /* HAVE_BLAKE2 || HAVE_BLAKE2S */
#endif /* WOLF_CRYPT_BLAKE2_H */ #endif /* WOLF_CRYPT_BLAKE2_H */

View File

@ -52,6 +52,9 @@
#ifdef WOLFSSL_MD2 #ifdef WOLFSSL_MD2
#include <wolfssl/wolfcrypt/md2.h> #include <wolfssl/wolfcrypt/md2.h>
#endif #endif
#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
#include <wolfssl/wolfcrypt/blake2.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -84,9 +84,12 @@ enum {
#ifndef WOLFSSL_SHA384 #ifndef WOLFSSL_SHA384
WC_SHA384 = WC_HASH_TYPE_SHA384, WC_SHA384 = WC_HASH_TYPE_SHA384,
#endif #endif
#ifndef HAVE_BLAKE2 #ifndef HAVE_BLAKE2B
BLAKE2B_ID = WC_HASH_TYPE_BLAKE2B, BLAKE2B_ID = WC_HASH_TYPE_BLAKE2B,
#endif #endif
#ifndef HAVE_BLAKE2S
BLAKE2S_ID = WC_HASH_TYPE_BLAKE2S,
#endif
#ifndef WOLFSSL_SHA224 #ifndef WOLFSSL_SHA224
WC_SHA224 = WC_HASH_TYPE_SHA224, WC_SHA224 = WC_HASH_TYPE_SHA224,
#endif #endif

View File

@ -611,7 +611,8 @@
enum wc_HashType { enum wc_HashType {
#if defined(HAVE_SELFTEST) || defined(HAVE_FIPS) #if defined(HAVE_SELFTEST) || defined(HAVE_FIPS)
/* In selftest build, WC_* types are not mapped to WC_HASH_TYPE types. /* In selftest build, WC_* types are not mapped to WC_HASH_TYPE types.
* Values here are based on old selftest hmac.h enum, with additions */ * Values here are based on old selftest hmac.h enum, with additions.
* These values are fixed for backwards FIPS compatibility */
WC_HASH_TYPE_NONE = 15, WC_HASH_TYPE_NONE = 15,
WC_HASH_TYPE_MD2 = 16, WC_HASH_TYPE_MD2 = 16,
WC_HASH_TYPE_MD4 = 17, WC_HASH_TYPE_MD4 = 17,
@ -627,8 +628,9 @@
WC_HASH_TYPE_SHA3_384 = 12, WC_HASH_TYPE_SHA3_384 = 12,
WC_HASH_TYPE_SHA3_512 = 13, WC_HASH_TYPE_SHA3_512 = 13,
WC_HASH_TYPE_BLAKE2B = 14, WC_HASH_TYPE_BLAKE2B = 14,
WC_HASH_TYPE_BLAKE2S = 19,
WC_HASH_TYPE_MAX = WC_HASH_TYPE_MD5_SHA WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S
#else #else
WC_HASH_TYPE_NONE = 0, WC_HASH_TYPE_NONE = 0,
WC_HASH_TYPE_MD2 = 1, WC_HASH_TYPE_MD2 = 1,
@ -645,8 +647,9 @@
WC_HASH_TYPE_SHA3_384 = 12, WC_HASH_TYPE_SHA3_384 = 12,
WC_HASH_TYPE_SHA3_512 = 13, WC_HASH_TYPE_SHA3_512 = 13,
WC_HASH_TYPE_BLAKE2B = 14, WC_HASH_TYPE_BLAKE2B = 14,
WC_HASH_TYPE_BLAKE2S = 15,
WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2B WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S
#endif /* HAVE_SELFTEST */ #endif /* HAVE_SELFTEST */
}; };