Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Add blake2s in the list of supported checksums
Baptiste Daroussin committed 9 years ago
commit e3285b5d03542a663e7fb97bc155ccd71af6226d
parent 255b373
6 files changed +451 -3
modified external/blake2/Makefile.am
@@ -4,8 +4,8 @@ noinst_HEADERS= blake2.h \
noinst_LTLIBRARIES=	libblake2.la libblake2_static.la

blake2_common_cflags=	-I$(top_srcdir)/compat -O3
-
libblake2_la_SOURCES=	blake2b-ref.c
+
libblake2_la_SOURCES=	blake2b-ref.c blake2s-ref.c
libblake2_la_CFLAGS=	$(blake2_common_cflags) -shared
libblake2_static_la_SOURCES=	$(libblake2_la_SOURCES)
libblake2_static_la_CFLAGS=	$(blake2_common_cflags) -static
-
libblake2_static_la_LDFLAGS=	-all-static

\ No newline at end of file
+
libblake2_static_la_LDFLAGS=	-all-static
added external/blake2/blake2s-ref.c
@@ -0,0 +1,369 @@
+
/*
+
   BLAKE2 reference source code package - reference C implementations
+
  
+
   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
+
   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
+
   your option.  The terms of these licenses can be found at:
+
  
+
   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+
   - OpenSSL license   : https://www.openssl.org/source/license.html
+
   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+
  
+
   More information about the BLAKE2 hash function can be found at
+
   https://blake2.net.
+
*/
+

+
#include <stdint.h>
+
#include <string.h>
+
#include <stdio.h>
+

+
#include "blake2.h"
+
#include "blake2-impl.h"
+

+
static const uint32_t blake2s_IV[8] =
+
{
+
  0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
+
  0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
+
};
+

+
static const uint8_t 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 void blake2s_set_lastnode( blake2s_state *S )
+
{
+
  S->f[1] = (uint32_t)-1;
+
}
+

+
/* Some helper functions, not necessarily useful */
+
static int blake2s_is_lastblock( const blake2s_state *S )
+
{
+
  return S->f[0] != 0;
+
}
+

+
static void blake2s_set_lastblock( blake2s_state *S )
+
{
+
  if( S->last_node ) blake2s_set_lastnode( S );
+

+
  S->f[0] = (uint32_t)-1;
+
}
+

+
static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
+
{
+
  S->t[0] += inc;
+
  S->t[1] += ( S->t[0] < inc );
+
}
+

+
static void blake2s_init0( blake2s_state *S )
+
{
+
  size_t i;
+
  memset( S, 0, sizeof( blake2s_state ) );
+

+
  for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
+
}
+

+
/* init2 xors IV with input parameter block */
+
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
+
{
+
  const unsigned char *p = ( const unsigned char * )( P );
+
  size_t i;
+

+
  blake2s_init0( S );
+

+
  /* IV XOR ParamBlock */
+
  for( i = 0; i < 8; ++i )
+
    S->h[i] ^= load32( &p[i * 4] );
+

+
  S->outlen = P->digest_length;
+
  return 0;
+
}
+

+

+
/* Sequential blake2s initialization */
+
int blake2s_init( blake2s_state *S, size_t outlen )
+
{
+
  blake2s_param P[1];
+

+
  /* Move interval verification here? */
+
  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
+

+
  P->digest_length = (uint8_t)outlen;
+
  P->key_length    = 0;
+
  P->fanout        = 1;
+
  P->depth         = 1;
+
  store32( &P->leaf_length, 0 );
+
  store32( &P->node_offset, 0 );
+
  store16( &P->xof_length, 0 );
+
  P->node_depth    = 0;
+
  P->inner_length  = 0;
+
  /* memset(P->reserved, 0, sizeof(P->reserved) ); */
+
  memset( P->salt,     0, sizeof( P->salt ) );
+
  memset( P->personal, 0, sizeof( P->personal ) );
+
  return blake2s_init_param( S, P );
+
}
+

+
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
+
{
+
  blake2s_param P[1];
+

+
  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
+

+
  if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
+

+
  P->digest_length = (uint8_t)outlen;
+
  P->key_length    = (uint8_t)keylen;
+
  P->fanout        = 1;
+
  P->depth         = 1;
+
  store32( &P->leaf_length, 0 );
+
  store32( &P->node_offset, 0 );
+
  store16( &P->xof_length, 0 );
+
  P->node_depth    = 0;
+
  P->inner_length  = 0;
+
  /* memset(P->reserved, 0, sizeof(P->reserved) ); */
+
  memset( P->salt,     0, sizeof( P->salt ) );
+
  memset( P->personal, 0, sizeof( P->personal ) );
+

+
  if( blake2s_init_param( S, P ) < 0 ) return -1;
+

+
  {
+
    uint8_t block[BLAKE2S_BLOCKBYTES];
+
    memset( block, 0, BLAKE2S_BLOCKBYTES );
+
    memcpy( block, key, keylen );
+
    blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
+
    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
+
  }
+
  return 0;
+
}
+

+
#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)
+

+
static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
+
{
+
  uint32_t m[16];
+
  uint32_t v[16];
+
  size_t i;
+

+
  for( i = 0; i < 16; ++i ) {
+
    m[i] = load32( in + 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];
+

+
  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
+

+
int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
+
{
+
  const unsigned char * in = (const unsigned char *)pin;
+
  if( inlen > 0 )
+
  {
+
    size_t left = S->buflen;
+
    size_t fill = BLAKE2S_BLOCKBYTES - left;
+
    if( inlen > fill )
+
    {
+
      S->buflen = 0;
+
      memcpy( S->buf + left, in, fill ); /* Fill buffer */
+
      blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
+
      blake2s_compress( S, S->buf ); /* Compress */
+
      in += fill; inlen -= fill;
+
      while(inlen > BLAKE2S_BLOCKBYTES) {
+
        blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
+
        blake2s_compress( S, in );
+
        in += BLAKE2S_BLOCKBYTES;
+
        inlen -= BLAKE2S_BLOCKBYTES;
+
      }
+
    }
+
    memcpy( S->buf + S->buflen, in, inlen );
+
    S->buflen += inlen;
+
  }
+
  return 0;
+
}
+

+
int blake2s_final( blake2s_state *S, void *out, size_t outlen )
+
{
+
  uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
+
  size_t i;
+

+
  if( out == NULL || outlen < S->outlen )
+
    return -1;
+

+
  if( blake2s_is_lastblock( S ) )
+
    return -1;
+

+
  blake2s_increment_counter( S, ( uint32_t )S->buflen );
+
  blake2s_set_lastblock( S );
+
  memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
+
  blake2s_compress( S, S->buf );
+

+
  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 );
+
  secure_zero_memory(buffer, sizeof(buffer));
+
  return 0;
+
}
+

+
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
+
{
+
  blake2s_state S[1];
+

+
  /* Verify parameters */
+
  if ( NULL == in && inlen > 0 ) return -1;
+

+
  if ( NULL == out ) return -1;
+

+
  if ( NULL == key && keylen > 0) return -1;
+

+
  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
+

+
  if( keylen > BLAKE2S_KEYBYTES ) return -1;
+

+
  if( keylen > 0 )
+
  {
+
    if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
+
  }
+
  else
+
  {
+
    if( blake2s_init( S, outlen ) < 0 ) return -1;
+
  }
+

+
  blake2s_update( S, ( const uint8_t * )in, inlen );
+
  blake2s_final( S, out, outlen );
+
  return 0;
+
}
+

+
#if defined(SUPERCOP)
+
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
+
{
+
  return blake2s( out, BLAKE2S_OUTBYTES in, inlen, NULL, 0 );
+
}
+
#endif
+

+
#if defined(BLAKE2S_SELFTEST)
+
#include <string.h>
+
#include "blake2-kat.h"
+
int main( void )
+
{
+
  uint8_t key[BLAKE2S_KEYBYTES];
+
  uint8_t buf[BLAKE2_KAT_LENGTH];
+
  size_t i, step;
+

+
  for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
+
    key[i] = ( uint8_t )i;
+

+
  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[BLAKE2S_OUTBYTES];
+
    blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
+

+
    if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
+
    {
+
      goto fail;
+
    }
+
  }
+

+
  /* Test streaming API */
+
  for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
+
    for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
+
      uint8_t hash[BLAKE2S_OUTBYTES];
+
      blake2s_state S;
+
      uint8_t * p = buf;
+
      size_t mlen = i;
+
      int err = 0;
+

+
      if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
+
        goto fail;
+
      }
+

+
      while (mlen >= step) {
+
        if ( (err = blake2s_update(&S, p, step)) < 0 ) {
+
          goto fail;
+
        }
+
        mlen -= step;
+
        p += step;
+
      }
+
      if ( (err = blake2s_update(&S, p, mlen)) < 0) {
+
        goto fail;
+
      }
+
      if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
+
        goto fail;
+
      }
+

+
      if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {
+
        goto fail;
+
      }
+
    }
+
  }
+

+
  puts( "ok" );
+
  return 0;
+
fail:
+
  puts("error");
+
  return -1;
+
}
+
#endif
+

+

modified libpkg/pkg_checksum.c
@@ -46,6 +46,7 @@ struct pkg_checksum_entry {
/* Hash is in format <version>:<typeid>:<hexhash> */
#define PKG_CHECKSUM_SHA256_LEN (SHA256_BLOCK_SIZE * 2 + 1)
#define PKG_CHECKSUM_BLAKE2_LEN (BLAKE2B_OUTBYTES * 8 / 5 + sizeof("100") * 2 + 2)
+
#define PKG_CHECKSUM_BLAKE2S_LEN (BLAKE2S_OUTBYTES * 8 / 5 + sizeof("100") * 2 + 2)
#define PKG_CHECKSUM_CUR_VERSION 2

typedef void (*pkg_checksum_hash_func)(struct pkg_checksum_entry *entries,
@@ -70,6 +71,12 @@ static void pkg_checksum_hash_blake2_bulk(const unsigned char *in, size_t inlen,
				unsigned char **out, size_t *outlen);
static void pkg_checksum_hash_blake2_file(int fd, unsigned char **out,
    size_t *outlen);
+
static void pkg_checksum_hash_blake2s(struct pkg_checksum_entry *entries,
+
				unsigned char **out, size_t *outlen);
+
static void pkg_checksum_hash_blake2s_bulk(const unsigned char *in, size_t inlen,
+
				unsigned char **out, size_t *outlen);
+
static void pkg_checksum_hash_blake2s_file(int fd, unsigned char **out,
+
    size_t *outlen);
static void pkg_checksum_encode_base32(unsigned char *in, size_t inlen,
				char *out, size_t outlen);
static void pkg_checksum_encode_hex(unsigned char *in, size_t inlen,
@@ -123,6 +130,22 @@ static const struct _pkg_cksum_type {
		pkg_checksum_hash_blake2_file,
		NULL
	},
+
	[PKG_HASH_TYPE_BLAKE2S_BASE32] = {
+
		"blake2s_base32",
+
		PKG_CHECKSUM_BLAKE2S_LEN,
+
		pkg_checksum_hash_blake2s,
+
		pkg_checksum_hash_blake2s_bulk,
+
		pkg_checksum_hash_blake2s_file,
+
		pkg_checksum_encode_base32
+
	},
+
	[PKG_HASH_TYPE_BLAKE2S_RAW] = {
+
		"blake2_raw",
+
		BLAKE2S_OUTBYTES,
+
		pkg_checksum_hash_blake2s,
+
		pkg_checksum_hash_blake2s_bulk,
+
		pkg_checksum_hash_blake2s_file,
+
		NULL
+
	},
	[PKG_HASH_TYPE_UNKNOWN] = {
		NULL,
		-1,
@@ -445,6 +468,56 @@ pkg_checksum_hash_blake2_file(int fd, unsigned char **out, size_t *outlen)
	*outlen = BLAKE2B_OUTBYTES;
}

+
static void
+
pkg_checksum_hash_blake2s(struct pkg_checksum_entry *entries,
+
		unsigned char **out, size_t *outlen)
+
{
+
	blake2s_state st;
+

+
	blake2s_init (&st, BLAKE2S_OUTBYTES);
+

+
	while(entries) {
+
		blake2s_update (&st, entries->field, strlen(entries->field));
+
		blake2s_update (&st, entries->value, strlen(entries->value));
+
		entries = entries->next;
+
	}
+
	*out = malloc(BLAKE2S_OUTBYTES);
+
	if (*out != NULL) {
+
		blake2s_final (&st, *out, BLAKE2S_OUTBYTES);
+
		*outlen = BLAKE2S_OUTBYTES;
+
	}
+
	else {
+
		pkg_emit_errno("malloc", "pkg_checksum_hash_blake2s");
+
		*outlen = 0;
+
	}
+
}
+

+
static void
+
pkg_checksum_hash_blake2s_bulk(const unsigned char *in, size_t inlen,
+
				unsigned char **out, size_t *outlen)
+
{
+
	*out = malloc(BLAKE2S_OUTBYTES);
+
	blake2s(*out, BLAKE2S_OUTBYTES,  in, inlen, NULL, 0);
+
	*outlen = BLAKE2S_OUTBYTES;
+
}
+

+
static void
+
pkg_checksum_hash_blake2s_file(int fd, unsigned char **out, size_t *outlen)
+
{
+
	char buffer[8192];
+
	size_t r;
+

+
	blake2s_state st;
+
	blake2s_init(&st, BLAKE2S_OUTBYTES);
+

+
	while ((r = read(fd, buffer, sizeof(buffer))) > 0)
+
		blake2s_update(&st, buffer, r);
+

+
	*out = malloc(BLAKE2S_OUTBYTES);
+
	blake2s_final(&st, *out, BLAKE2S_OUTBYTES);
+
	*outlen = BLAKE2S_OUTBYTES;
+
}
+

/*
 * We use here z-base32 encoding described here:
 * http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
modified libpkg/pkg_repo_meta.c
@@ -98,7 +98,7 @@ pkg_repo_meta_open_schema_v1()
			"maintainer = {type = string};\n"
			"source = {type = string};\n"
			"packing_format = {enum = [txz, tbz, tgz, tar]};\n"
-
			"digest_format = {enum = [sha256_base32, sha256_hex, blake2_base32]};\n"
+
			"digest_format = {enum = [sha256_base32, sha256_hex, blake2_base32, blake2s_base32]};\n"
			"digests = {type = string};\n"
			"manifests = {type = string};\n"
			"conflicts = {type = string};\n"
modified libpkg/private/pkg.h
@@ -403,6 +403,8 @@ typedef enum pkg_checksum_type_e {
	PKG_HASH_TYPE_BLAKE2_BASE32,
	PKG_HASH_TYPE_SHA256_RAW,
	PKG_HASH_TYPE_BLAKE2_RAW,
+
	PKG_HASH_TYPE_BLAKE2S_BASE32,
+
	PKG_HASH_TYPE_BLAKE2S_RAW,
	PKG_HASH_TYPE_UNKNOWN
} pkg_checksum_type_t;

modified tests/lib/checksum.c
@@ -56,8 +56,12 @@ ATF_TC_BODY(check_symlinks, tc)
	sum = pkg_checksum_generate_file("bar", PKG_HASH_TYPE_BLAKE2_BASE32);
	ATF_REQUIRE_STREQ(sum, "2$kgygnaah7wxsgn1wkuic4j78zq8dicmx53picmma99ogmkbd7k5nhuxr5xxemz6yzjab15oor3tjt7nupj8mh764y7kddbne7qw9agn");
	free(sum);
+
	sum = pkg_checksum_generate_file("bar", PKG_HASH_TYPE_BLAKE2S_BASE32);
+
	ATF_REQUIRE_STREQ(sum, "5$eoiiccdoiuz9acwfo7fxi6abnrfdtg81mz5ccx7tbg5ny9755g7y");
+
	free(sum);

	ATF_CHECK(pkg_checksum_validate_file("bar", "2$kgygnaah7wxsgn1wkuic4j78zq8dicmx53picmma99ogmkbd7k5nhuxr5xxemz6yzjab15oor3tjt7nupj8mh764y7kddbne7qw9agn") == 0);
+
	ATF_CHECK(pkg_checksum_validate_file("bar", "5$eoiiccdoiuz9acwfo7fxi6abnrfdtg81mz5ccx7tbg5ny9755g7y") == 0);
	ATF_CHECK(pkg_checksum_validate_file("bar", "1$2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae") == 0);
}