shithub: blake2

Download patch

ref: 932be4e9f5c973a2aa49656447683fbfae4cfb39
parent: 64cafcff1620ab778d23057e1c7559087d7bd4e6
author: Samuel Neves <sneves@dei.uc.pt>
date: Sat Jun 11 08:42:46 EDT 2016

outlen in blake2xx_final should be the output buffer size, not the hash length

--- a/ref/blake2.h
+++ b/ref/blake2.h
@@ -53,6 +53,7 @@
     uint32_t f[2];
     uint8_t  buf[BLAKE2S_BLOCKBYTES];
     size_t   buflen;
+    size_t   outlen;
     uint8_t  last_node;
   } blake2s_state;
 
@@ -63,6 +64,7 @@
     uint64_t f[2];
     uint8_t  buf[BLAKE2B_BLOCKBYTES];
     size_t   buflen;
+    size_t   outlen;
     uint8_t  last_node;
   } blake2b_state;
 
@@ -72,6 +74,7 @@
     blake2s_state R[1];
     uint8_t       buf[8 * BLAKE2S_BLOCKBYTES];
     size_t        buflen;
+    size_t        outlen;
   } blake2sp_state;
 
   typedef struct blake2bp_state__
@@ -80,6 +83,7 @@
     blake2b_state R[1];
     uint8_t       buf[4 * BLAKE2B_BLOCKBYTES];
     size_t        buflen;
+    size_t        outlen;
   } blake2bp_state;
 
 
--- a/ref/blake2b-ref.c
+++ b/ref/blake2b-ref.c
@@ -101,6 +101,7 @@
   for( i = 0; i < 8; ++i )
     S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
 
+  S->outlen = P->digest_length;
   return 0;
 }
 
@@ -259,7 +260,7 @@
   uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
   size_t i;
 
-  if( out == NULL || outlen == 0 || outlen > BLAKE2B_OUTBYTES )
+  if( out == NULL || outlen < S->outlen )
     return -1;
 
   if( blake2b_is_lastblock( S ) )
@@ -273,7 +274,7 @@
   for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
     store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
 
-  memcpy( out, buffer, outlen );
+  memcpy( out, buffer, S->outlen );
   secure_zero_memory(buffer, sizeof(buffer));
   return 0;
 }
@@ -326,7 +327,7 @@
 {
   uint8_t key[BLAKE2B_KEYBYTES];
   uint8_t buf[BLAKE2_KAT_LENGTH];
-  size_t i;
+  size_t i, step;
 
   for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
     key[i] = ( uint8_t )i;
@@ -334,6 +335,7 @@
   for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
     buf[i] = ( uint8_t )i;
 
+  /* Test simple API */
   for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
   {
     uint8_t hash[BLAKE2B_OUTBYTES];
@@ -341,13 +343,48 @@
 
     if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
     {
-      puts( "error" );
-      return -1;
+      goto fail;
     }
   }
 
+  /* Test streaming API */
+  for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
+    for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
+      uint8_t hash[BLAKE2B_OUTBYTES];
+      blake2b_state S;
+      uint8_t * p = buf;
+      size_t mlen = i;
+      int err = 0;
+
+      if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {
+        goto fail;
+      }
+
+      while (mlen >= step) {
+        if ( (err = blake2b_update(&S, p, step)) < 0 ) {
+          goto fail;
+        }
+        mlen -= step;
+        p += step;
+      }
+      if ( (err = blake2b_update(&S, p, mlen)) < 0) {
+        goto fail;
+      }
+      if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
+        goto fail;
+      }
+
+      if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
+        goto fail;
+      }
+    }
+  }
+
   puts( "ok" );
   return 0;
+fail:
+  puts("error");
+  return -1;
 }
 #endif
 
--- a/ref/blake2bp-ref.c
+++ b/ref/blake2bp-ref.c
@@ -70,6 +70,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )
     return -1;
@@ -92,6 +93,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )
     return -1;
@@ -171,6 +173,10 @@
   uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
   size_t i;
 
+  if(out == NULL || outlen < S->outlen) {
+    return -1;
+  }
+
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
   {
     if( S->buflen > i * BLAKE2B_BLOCKBYTES )
@@ -188,7 +194,7 @@
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
     blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
 
-  return blake2b_final( S->R, out, outlen );
+  return blake2b_final( S->R, out, S->outlen );
 }
 
 int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
--- a/ref/blake2s-ref.c
+++ b/ref/blake2s-ref.c
@@ -96,6 +96,7 @@
   for( i = 0; i < 8; ++i )
     S->h[i] ^= load32( &p[i * 4] );
 
+  S->outlen = P->digest_length;
   return 0;
 }
 
@@ -252,7 +253,7 @@
   uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
   size_t i;
 
-  if( out == NULL || outlen == 0 || outlen > BLAKE2S_OUTBYTES )
+  if( out == NULL || outlen < S->outlen )
     return -1;
 
   if( blake2s_is_lastblock( S ) )
--- a/ref/blake2sp-ref.c
+++ b/ref/blake2sp-ref.c
@@ -67,6 +67,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
     return -1;
@@ -89,6 +90,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
     return -1;
@@ -168,6 +170,10 @@
   uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
   size_t i;
 
+  if(out == NULL || outlen < S->outlen) {
+    return -1;
+  }
+
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
   {
     if( S->buflen > i * BLAKE2S_BLOCKBYTES )
@@ -185,7 +191,7 @@
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
     blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
 
-  return blake2s_final( S->R, out, outlen );
+  return blake2s_final( S->R, out, S->outlen );
 }
 
 
--- a/sse/blake2.h
+++ b/sse/blake2.h
@@ -53,6 +53,7 @@
     uint32_t f[2];
     uint8_t  buf[BLAKE2S_BLOCKBYTES];
     size_t   buflen;
+    size_t   outlen;
     uint8_t  last_node;
   } blake2s_state;
 
@@ -63,6 +64,7 @@
     uint64_t f[2];
     uint8_t  buf[BLAKE2B_BLOCKBYTES];
     size_t   buflen;
+    size_t   outlen;
     uint8_t  last_node;
   } blake2b_state;
 
@@ -72,6 +74,7 @@
     blake2s_state R[1];
     uint8_t       buf[8 * BLAKE2S_BLOCKBYTES];
     size_t        buflen;
+    size_t        outlen;
   } blake2sp_state;
 
   typedef struct blake2bp_state__
@@ -80,6 +83,7 @@
     blake2b_state R[1];
     uint8_t       buf[4 * BLAKE2B_BLOCKBYTES];
     size_t        buflen;
+    size_t        outlen;
   } blake2bp_state;
 
 
--- a/sse/blake2b.c
+++ b/sse/blake2b.c
@@ -124,6 +124,7 @@
 
   for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
 
+  S->outlen = P->digest_length;
   return 0;
 }
 
@@ -285,7 +286,7 @@
 
 int blake2b_final( blake2b_state *S, void *out, size_t outlen )
 {
-  if( outlen > BLAKE2B_OUTBYTES )
+  if( out == NULL || outlen < S->outlen )
     return -1;
 
   if( blake2b_is_lastblock( S ) )
@@ -296,7 +297,7 @@
   memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
   blake2b_compress( S, S->buf );
 
-  memcpy( out, &S->h[0], outlen );
+  memcpy( out, &S->h[0], S->outlen );
   return 0;
 }
 
--- a/sse/blake2bp.c
+++ b/sse/blake2bp.c
@@ -69,6 +69,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )
     return -1;
@@ -91,6 +92,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )
     return -1;
@@ -172,6 +174,10 @@
   uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
   size_t i;
 
+  if(out == NULL || outlen < S->outlen) {
+    return -1;
+  }
+
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
   {
     if( S->buflen > i * BLAKE2B_BLOCKBYTES )
@@ -189,7 +195,7 @@
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
     blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
 
-  return blake2b_final( S->R, out, outlen );
+  return blake2b_final( S->R, out, S->outlen );
 }
 
 int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
--- a/sse/blake2s.c
+++ b/sse/blake2s.c
@@ -119,6 +119,7 @@
 
   for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
 
+  S->outlen = P->digest_length;
   return 0;
 }
 
@@ -268,7 +269,7 @@
   uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
   size_t i;
 
-  if( outlen > BLAKE2S_OUTBYTES )
+  if( out == NULL || outlen < S->outlen )
     return -1;
 
   if( blake2s_is_lastblock( S ) )
@@ -282,7 +283,7 @@
   for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
     store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
 
-  memcpy( out, buffer, outlen );
+  memcpy( out, buffer, S->outlen );
   secure_zero_memory( buffer, sizeof(buffer) );
   return 0;
 }
--- a/sse/blake2sp.c
+++ b/sse/blake2sp.c
@@ -67,6 +67,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
     return -1;
@@ -89,6 +90,7 @@
 
   memset( S->buf, 0, sizeof( S->buf ) );
   S->buflen = 0;
+  S->outlen = outlen;
 
   if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
     return -1;
@@ -169,6 +171,10 @@
   uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
   size_t i;
 
+  if(out == NULL || outlen < S->outlen) {
+    return -1;
+  }
+
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
   {
     if( S->buflen > i * BLAKE2S_BLOCKBYTES )
@@ -186,7 +192,7 @@
   for( i = 0; i < PARALLELISM_DEGREE; ++i )
     blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
 
-  return blake2s_final( S->R, out, outlen );
+  return blake2s_final( S->R, out, S->outlen );
 }
 
 
--