fork of cyassl-lib

Dependents:   TLS_cyassl TLS_cyassl

Committer:
feb11
Date:
Mon Sep 16 09:53:35 2013 +0000
Revision:
4:f377303c41be
Parent:
0:714293de3836
changed settings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:714293de3836 1 /*
ashleymills 0:714293de3836 2 BLAKE2 reference source code package - reference C implementations
ashleymills 0:714293de3836 3
ashleymills 0:714293de3836 4 Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
ashleymills 0:714293de3836 5
ashleymills 0:714293de3836 6 To the extent possible under law, the author(s) have dedicated all copyright
ashleymills 0:714293de3836 7 and related and neighboring rights to this software to the public domain
ashleymills 0:714293de3836 8 worldwide. This software is distributed without any warranty.
ashleymills 0:714293de3836 9
ashleymills 0:714293de3836 10 You should have received a copy of the CC0 Public Domain Dedication along with
ashleymills 0:714293de3836 11 this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
ashleymills 0:714293de3836 12 */
ashleymills 0:714293de3836 13 /* blake2b.c
ashleymills 0:714293de3836 14 *
ashleymills 0:714293de3836 15 * Copyright (C) 2006-2013 wolfSSL Inc.
ashleymills 0:714293de3836 16 *
ashleymills 0:714293de3836 17 * This file is part of CyaSSL.
ashleymills 0:714293de3836 18 *
ashleymills 0:714293de3836 19 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:714293de3836 20 * it under the terms of the GNU General Public License as published by
ashleymills 0:714293de3836 21 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:714293de3836 22 * (at your option) any later version.
ashleymills 0:714293de3836 23 *
ashleymills 0:714293de3836 24 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:714293de3836 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:714293de3836 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:714293de3836 27 * GNU General Public License for more details.
ashleymills 0:714293de3836 28 *
ashleymills 0:714293de3836 29 * You should have received a copy of the GNU General Public License
ashleymills 0:714293de3836 30 * along with this program; if not, write to the Free Software
ashleymills 0:714293de3836 31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:714293de3836 32 */
ashleymills 0:714293de3836 33
ashleymills 0:714293de3836 34
ashleymills 0:714293de3836 35 #ifdef HAVE_CONFIG_H
ashleymills 0:714293de3836 36 #include <config.h>
ashleymills 0:714293de3836 37 #endif
ashleymills 0:714293de3836 38
ashleymills 0:714293de3836 39 #include <cyassl/ctaocrypt/settings.h>
ashleymills 0:714293de3836 40
ashleymills 0:714293de3836 41 #ifdef HAVE_BLAKE2
ashleymills 0:714293de3836 42
ashleymills 0:714293de3836 43 #include <cyassl/ctaocrypt/blake2.h>
ashleymills 0:714293de3836 44 #include <cyassl/ctaocrypt/blake2-impl.h>
ashleymills 0:714293de3836 45
ashleymills 0:714293de3836 46
ashleymills 0:714293de3836 47 static const word64 blake2b_IV[8] =
ashleymills 0:714293de3836 48 {
ashleymills 0:714293de3836 49 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
ashleymills 0:714293de3836 50 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
ashleymills 0:714293de3836 51 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
ashleymills 0:714293de3836 52 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
ashleymills 0:714293de3836 53 };
ashleymills 0:714293de3836 54
ashleymills 0:714293de3836 55 static const byte blake2b_sigma[12][16] =
ashleymills 0:714293de3836 56 {
ashleymills 0:714293de3836 57 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
ashleymills 0:714293de3836 58 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
ashleymills 0:714293de3836 59 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
ashleymills 0:714293de3836 60 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
ashleymills 0:714293de3836 61 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
ashleymills 0:714293de3836 62 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
ashleymills 0:714293de3836 63 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
ashleymills 0:714293de3836 64 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
ashleymills 0:714293de3836 65 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
ashleymills 0:714293de3836 66 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
ashleymills 0:714293de3836 67 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
ashleymills 0:714293de3836 68 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
ashleymills 0:714293de3836 69 };
ashleymills 0:714293de3836 70
ashleymills 0:714293de3836 71
ashleymills 0:714293de3836 72 static INLINE int blake2b_set_lastnode( blake2b_state *S )
ashleymills 0:714293de3836 73 {
ashleymills 0:714293de3836 74 S->f[1] = ~0ULL;
ashleymills 0:714293de3836 75 return 0;
ashleymills 0:714293de3836 76 }
ashleymills 0:714293de3836 77
ashleymills 0:714293de3836 78 static INLINE int blake2b_clear_lastnode( blake2b_state *S )
ashleymills 0:714293de3836 79 {
ashleymills 0:714293de3836 80 S->f[1] = 0ULL;
ashleymills 0:714293de3836 81 return 0;
ashleymills 0:714293de3836 82 }
ashleymills 0:714293de3836 83
ashleymills 0:714293de3836 84 /* Some helper functions, not necessarily useful */
ashleymills 0:714293de3836 85 static INLINE int blake2b_set_lastblock( blake2b_state *S )
ashleymills 0:714293de3836 86 {
ashleymills 0:714293de3836 87 if( S->last_node ) blake2b_set_lastnode( S );
ashleymills 0:714293de3836 88
ashleymills 0:714293de3836 89 S->f[0] = ~0ULL;
ashleymills 0:714293de3836 90 return 0;
ashleymills 0:714293de3836 91 }
ashleymills 0:714293de3836 92
ashleymills 0:714293de3836 93 static INLINE int blake2b_clear_lastblock( blake2b_state *S )
ashleymills 0:714293de3836 94 {
ashleymills 0:714293de3836 95 if( S->last_node ) blake2b_clear_lastnode( S );
ashleymills 0:714293de3836 96
ashleymills 0:714293de3836 97 S->f[0] = 0ULL;
ashleymills 0:714293de3836 98 return 0;
ashleymills 0:714293de3836 99 }
ashleymills 0:714293de3836 100
ashleymills 0:714293de3836 101 static INLINE int blake2b_increment_counter( blake2b_state *S, const word64
ashleymills 0:714293de3836 102 inc )
ashleymills 0:714293de3836 103 {
ashleymills 0:714293de3836 104 S->t[0] += inc;
ashleymills 0:714293de3836 105 S->t[1] += ( S->t[0] < inc );
ashleymills 0:714293de3836 106 return 0;
ashleymills 0:714293de3836 107 }
ashleymills 0:714293de3836 108
ashleymills 0:714293de3836 109
ashleymills 0:714293de3836 110
ashleymills 0:714293de3836 111 /* Parameter-related functions */
ashleymills 0:714293de3836 112 static INLINE int blake2b_param_set_digest_length( blake2b_param *P,
ashleymills 0:714293de3836 113 const byte digest_length )
ashleymills 0:714293de3836 114 {
ashleymills 0:714293de3836 115 P->digest_length = digest_length;
ashleymills 0:714293de3836 116 return 0;
ashleymills 0:714293de3836 117 }
ashleymills 0:714293de3836 118
ashleymills 0:714293de3836 119 static INLINE int blake2b_param_set_fanout( blake2b_param *P, const byte fanout)
ashleymills 0:714293de3836 120 {
ashleymills 0:714293de3836 121 P->fanout = fanout;
ashleymills 0:714293de3836 122 return 0;
ashleymills 0:714293de3836 123 }
ashleymills 0:714293de3836 124
ashleymills 0:714293de3836 125 static INLINE int blake2b_param_set_max_depth( blake2b_param *P,
ashleymills 0:714293de3836 126 const byte depth )
ashleymills 0:714293de3836 127 {
ashleymills 0:714293de3836 128 P->depth = depth;
ashleymills 0:714293de3836 129 return 0;
ashleymills 0:714293de3836 130 }
ashleymills 0:714293de3836 131
ashleymills 0:714293de3836 132 static INLINE int blake2b_param_set_leaf_length( blake2b_param *P,
ashleymills 0:714293de3836 133 const word32 leaf_length )
ashleymills 0:714293de3836 134 {
ashleymills 0:714293de3836 135 store32( &P->leaf_length, leaf_length );
ashleymills 0:714293de3836 136 return 0;
ashleymills 0:714293de3836 137 }
ashleymills 0:714293de3836 138
ashleymills 0:714293de3836 139 static INLINE int blake2b_param_set_node_offset( blake2b_param *P,
ashleymills 0:714293de3836 140 const word64 node_offset )
ashleymills 0:714293de3836 141 {
ashleymills 0:714293de3836 142 store64( &P->node_offset, node_offset );
ashleymills 0:714293de3836 143 return 0;
ashleymills 0:714293de3836 144 }
ashleymills 0:714293de3836 145
ashleymills 0:714293de3836 146 static INLINE int blake2b_param_set_node_depth( blake2b_param *P,
ashleymills 0:714293de3836 147 const byte node_depth )
ashleymills 0:714293de3836 148 {
ashleymills 0:714293de3836 149 P->node_depth = node_depth;
ashleymills 0:714293de3836 150 return 0;
ashleymills 0:714293de3836 151 }
ashleymills 0:714293de3836 152
ashleymills 0:714293de3836 153 static INLINE int blake2b_param_set_inner_length( blake2b_param *P,
ashleymills 0:714293de3836 154 const byte inner_length )
ashleymills 0:714293de3836 155 {
ashleymills 0:714293de3836 156 P->inner_length = inner_length;
ashleymills 0:714293de3836 157 return 0;
ashleymills 0:714293de3836 158 }
ashleymills 0:714293de3836 159
ashleymills 0:714293de3836 160 static INLINE int blake2b_param_set_salt( blake2b_param *P,
ashleymills 0:714293de3836 161 const byte salt[BLAKE2B_SALTBYTES] )
ashleymills 0:714293de3836 162 {
ashleymills 0:714293de3836 163 XMEMCPY( P->salt, salt, BLAKE2B_SALTBYTES );
ashleymills 0:714293de3836 164 return 0;
ashleymills 0:714293de3836 165 }
ashleymills 0:714293de3836 166
ashleymills 0:714293de3836 167 static INLINE int blake2b_param_set_personal( blake2b_param *P,
ashleymills 0:714293de3836 168 const byte personal[BLAKE2B_PERSONALBYTES] )
ashleymills 0:714293de3836 169 {
ashleymills 0:714293de3836 170 XMEMCPY( P->personal, personal, BLAKE2B_PERSONALBYTES );
ashleymills 0:714293de3836 171 return 0;
ashleymills 0:714293de3836 172 }
ashleymills 0:714293de3836 173
ashleymills 0:714293de3836 174 static INLINE int blake2b_init0( blake2b_state *S )
ashleymills 0:714293de3836 175 {
ashleymills 0:714293de3836 176 int i;
ashleymills 0:714293de3836 177 XMEMSET( S, 0, sizeof( blake2b_state ) );
ashleymills 0:714293de3836 178
ashleymills 0:714293de3836 179 for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
ashleymills 0:714293de3836 180
ashleymills 0:714293de3836 181 return 0;
ashleymills 0:714293de3836 182 }
ashleymills 0:714293de3836 183
ashleymills 0:714293de3836 184 /* init xors IV with input parameter block */
ashleymills 0:714293de3836 185 int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
ashleymills 0:714293de3836 186 {
ashleymills 0:714293de3836 187 word32 i;
ashleymills 0:714293de3836 188 blake2b_init0( S );
ashleymills 0:714293de3836 189 byte *p = ( byte * )( P );
ashleymills 0:714293de3836 190
ashleymills 0:714293de3836 191 /* IV XOR ParamBlock */
ashleymills 0:714293de3836 192 for( i = 0; i < 8; ++i )
ashleymills 0:714293de3836 193 S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
ashleymills 0:714293de3836 194
ashleymills 0:714293de3836 195 return 0;
ashleymills 0:714293de3836 196 }
ashleymills 0:714293de3836 197
ashleymills 0:714293de3836 198
ashleymills 0:714293de3836 199
ashleymills 0:714293de3836 200 int blake2b_init( blake2b_state *S, const byte outlen )
ashleymills 0:714293de3836 201 {
ashleymills 0:714293de3836 202 blake2b_param P[1];
ashleymills 0:714293de3836 203
ashleymills 0:714293de3836 204 if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
ashleymills 0:714293de3836 205
ashleymills 0:714293de3836 206 P->digest_length = outlen;
ashleymills 0:714293de3836 207 P->key_length = 0;
ashleymills 0:714293de3836 208 P->fanout = 1;
ashleymills 0:714293de3836 209 P->depth = 1;
ashleymills 0:714293de3836 210 store32( &P->leaf_length, 0 );
ashleymills 0:714293de3836 211 store64( &P->node_offset, 0 );
ashleymills 0:714293de3836 212 P->node_depth = 0;
ashleymills 0:714293de3836 213 P->inner_length = 0;
ashleymills 0:714293de3836 214 XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
ashleymills 0:714293de3836 215 XMEMSET( P->salt, 0, sizeof( P->salt ) );
ashleymills 0:714293de3836 216 XMEMSET( P->personal, 0, sizeof( P->personal ) );
ashleymills 0:714293de3836 217 return blake2b_init_param( S, P );
ashleymills 0:714293de3836 218 }
ashleymills 0:714293de3836 219
ashleymills 0:714293de3836 220
ashleymills 0:714293de3836 221 int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key,
ashleymills 0:714293de3836 222 const byte keylen )
ashleymills 0:714293de3836 223 {
ashleymills 0:714293de3836 224 blake2b_param P[1];
ashleymills 0:714293de3836 225
ashleymills 0:714293de3836 226 if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
ashleymills 0:714293de3836 227
ashleymills 0:714293de3836 228 if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
ashleymills 0:714293de3836 229
ashleymills 0:714293de3836 230 P->digest_length = outlen;
ashleymills 0:714293de3836 231 P->key_length = keylen;
ashleymills 0:714293de3836 232 P->fanout = 1;
ashleymills 0:714293de3836 233 P->depth = 1;
ashleymills 0:714293de3836 234 store32( &P->leaf_length, 0 );
ashleymills 0:714293de3836 235 store64( &P->node_offset, 0 );
ashleymills 0:714293de3836 236 P->node_depth = 0;
ashleymills 0:714293de3836 237 P->inner_length = 0;
ashleymills 0:714293de3836 238 XMEMSET( P->reserved, 0, sizeof( P->reserved ) );
ashleymills 0:714293de3836 239 XMEMSET( P->salt, 0, sizeof( P->salt ) );
ashleymills 0:714293de3836 240 XMEMSET( P->personal, 0, sizeof( P->personal ) );
ashleymills 0:714293de3836 241
ashleymills 0:714293de3836 242 if( blake2b_init_param( S, P ) < 0 ) return -1;
ashleymills 0:714293de3836 243
ashleymills 0:714293de3836 244 {
ashleymills 0:714293de3836 245 byte block[BLAKE2B_BLOCKBYTES];
ashleymills 0:714293de3836 246 XMEMSET( block, 0, BLAKE2B_BLOCKBYTES );
ashleymills 0:714293de3836 247 XMEMCPY( block, key, keylen );
ashleymills 0:714293de3836 248 blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
ashleymills 0:714293de3836 249 secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */
ashleymills 0:714293de3836 250 /*stack */
ashleymills 0:714293de3836 251 }
ashleymills 0:714293de3836 252 return 0;
ashleymills 0:714293de3836 253 }
ashleymills 0:714293de3836 254
ashleymills 0:714293de3836 255 static int blake2b_compress( blake2b_state *S,
ashleymills 0:714293de3836 256 const byte block[BLAKE2B_BLOCKBYTES] )
ashleymills 0:714293de3836 257 {
ashleymills 0:714293de3836 258 word64 m[16];
ashleymills 0:714293de3836 259 word64 v[16];
ashleymills 0:714293de3836 260 int i;
ashleymills 0:714293de3836 261
ashleymills 0:714293de3836 262 for( i = 0; i < 16; ++i )
ashleymills 0:714293de3836 263 m[i] = load64( block + i * sizeof( m[i] ) );
ashleymills 0:714293de3836 264
ashleymills 0:714293de3836 265 for( i = 0; i < 8; ++i )
ashleymills 0:714293de3836 266 v[i] = S->h[i];
ashleymills 0:714293de3836 267
ashleymills 0:714293de3836 268 v[ 8] = blake2b_IV[0];
ashleymills 0:714293de3836 269 v[ 9] = blake2b_IV[1];
ashleymills 0:714293de3836 270 v[10] = blake2b_IV[2];
ashleymills 0:714293de3836 271 v[11] = blake2b_IV[3];
ashleymills 0:714293de3836 272 v[12] = S->t[0] ^ blake2b_IV[4];
ashleymills 0:714293de3836 273 v[13] = S->t[1] ^ blake2b_IV[5];
ashleymills 0:714293de3836 274 v[14] = S->f[0] ^ blake2b_IV[6];
ashleymills 0:714293de3836 275 v[15] = S->f[1] ^ blake2b_IV[7];
ashleymills 0:714293de3836 276 #define G(r,i,a,b,c,d) \
ashleymills 0:714293de3836 277 do { \
ashleymills 0:714293de3836 278 a = a + b + m[blake2b_sigma[r][2*i+0]]; \
ashleymills 0:714293de3836 279 d = rotr64(d ^ a, 32); \
ashleymills 0:714293de3836 280 c = c + d; \
ashleymills 0:714293de3836 281 b = rotr64(b ^ c, 24); \
ashleymills 0:714293de3836 282 a = a + b + m[blake2b_sigma[r][2*i+1]]; \
ashleymills 0:714293de3836 283 d = rotr64(d ^ a, 16); \
ashleymills 0:714293de3836 284 c = c + d; \
ashleymills 0:714293de3836 285 b = rotr64(b ^ c, 63); \
ashleymills 0:714293de3836 286 } while(0)
ashleymills 0:714293de3836 287 #define ROUND(r) \
ashleymills 0:714293de3836 288 do { \
ashleymills 0:714293de3836 289 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
ashleymills 0:714293de3836 290 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
ashleymills 0:714293de3836 291 G(r,2,v[ 2],v[ 6],v[10],v[14]); \
ashleymills 0:714293de3836 292 G(r,3,v[ 3],v[ 7],v[11],v[15]); \
ashleymills 0:714293de3836 293 G(r,4,v[ 0],v[ 5],v[10],v[15]); \
ashleymills 0:714293de3836 294 G(r,5,v[ 1],v[ 6],v[11],v[12]); \
ashleymills 0:714293de3836 295 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
ashleymills 0:714293de3836 296 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
ashleymills 0:714293de3836 297 } while(0)
ashleymills 0:714293de3836 298 ROUND( 0 );
ashleymills 0:714293de3836 299 ROUND( 1 );
ashleymills 0:714293de3836 300 ROUND( 2 );
ashleymills 0:714293de3836 301 ROUND( 3 );
ashleymills 0:714293de3836 302 ROUND( 4 );
ashleymills 0:714293de3836 303 ROUND( 5 );
ashleymills 0:714293de3836 304 ROUND( 6 );
ashleymills 0:714293de3836 305 ROUND( 7 );
ashleymills 0:714293de3836 306 ROUND( 8 );
ashleymills 0:714293de3836 307 ROUND( 9 );
ashleymills 0:714293de3836 308 ROUND( 10 );
ashleymills 0:714293de3836 309 ROUND( 11 );
ashleymills 0:714293de3836 310
ashleymills 0:714293de3836 311 for( i = 0; i < 8; ++i )
ashleymills 0:714293de3836 312 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
ashleymills 0:714293de3836 313
ashleymills 0:714293de3836 314 #undef G
ashleymills 0:714293de3836 315 #undef ROUND
ashleymills 0:714293de3836 316 return 0;
ashleymills 0:714293de3836 317 }
ashleymills 0:714293de3836 318
ashleymills 0:714293de3836 319 /* inlen now in bytes */
ashleymills 0:714293de3836 320 int blake2b_update( blake2b_state *S, const byte *in, word64 inlen )
ashleymills 0:714293de3836 321 {
ashleymills 0:714293de3836 322 while( inlen > 0 )
ashleymills 0:714293de3836 323 {
ashleymills 0:714293de3836 324 word64 left = S->buflen;
ashleymills 0:714293de3836 325 word64 fill = 2 * BLAKE2B_BLOCKBYTES - left;
ashleymills 0:714293de3836 326
ashleymills 0:714293de3836 327 if( inlen > fill )
ashleymills 0:714293de3836 328 {
ashleymills 0:714293de3836 329 XMEMCPY( S->buf + left, in, (word)fill ); /* Fill buffer */
ashleymills 0:714293de3836 330 S->buflen += fill;
ashleymills 0:714293de3836 331 blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
ashleymills 0:714293de3836 332 blake2b_compress( S, S->buf ); /* Compress */
ashleymills 0:714293de3836 333 XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
ashleymills 0:714293de3836 334 /* Shift buffer left */
ashleymills 0:714293de3836 335 S->buflen -= BLAKE2B_BLOCKBYTES;
ashleymills 0:714293de3836 336 in += fill;
ashleymills 0:714293de3836 337 inlen -= fill;
ashleymills 0:714293de3836 338 }
ashleymills 0:714293de3836 339 else /* inlen <= fill */
ashleymills 0:714293de3836 340 {
ashleymills 0:714293de3836 341 XMEMCPY( S->buf + left, in, (word)inlen );
ashleymills 0:714293de3836 342 S->buflen += inlen; /* Be lazy, do not compress */
ashleymills 0:714293de3836 343 in += inlen;
ashleymills 0:714293de3836 344 inlen -= inlen;
ashleymills 0:714293de3836 345 }
ashleymills 0:714293de3836 346 }
ashleymills 0:714293de3836 347
ashleymills 0:714293de3836 348 return 0;
ashleymills 0:714293de3836 349 }
ashleymills 0:714293de3836 350
ashleymills 0:714293de3836 351 /* Is this correct? */
ashleymills 0:714293de3836 352 int blake2b_final( blake2b_state *S, byte *out, byte outlen )
ashleymills 0:714293de3836 353 {
ashleymills 0:714293de3836 354 byte buffer[BLAKE2B_OUTBYTES];
ashleymills 0:714293de3836 355 int i;
ashleymills 0:714293de3836 356
ashleymills 0:714293de3836 357 if( S->buflen > BLAKE2B_BLOCKBYTES )
ashleymills 0:714293de3836 358 {
ashleymills 0:714293de3836 359 blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
ashleymills 0:714293de3836 360 blake2b_compress( S, S->buf );
ashleymills 0:714293de3836 361 S->buflen -= BLAKE2B_BLOCKBYTES;
ashleymills 0:714293de3836 362 XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (word)S->buflen );
ashleymills 0:714293de3836 363 }
ashleymills 0:714293de3836 364
ashleymills 0:714293de3836 365 blake2b_increment_counter( S, S->buflen );
ashleymills 0:714293de3836 366 blake2b_set_lastblock( S );
ashleymills 0:714293de3836 367 XMEMSET( S->buf + S->buflen, 0, (word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) );
ashleymills 0:714293de3836 368 /* Padding */
ashleymills 0:714293de3836 369 blake2b_compress( S, S->buf );
ashleymills 0:714293de3836 370
ashleymills 0:714293de3836 371 for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
ashleymills 0:714293de3836 372 store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
ashleymills 0:714293de3836 373
ashleymills 0:714293de3836 374 XMEMCPY( out, buffer, outlen );
ashleymills 0:714293de3836 375 return 0;
ashleymills 0:714293de3836 376 }
ashleymills 0:714293de3836 377
ashleymills 0:714293de3836 378 /* inlen, at least, should be word64. Others can be size_t. */
ashleymills 0:714293de3836 379 int blake2b( byte *out, const void *in, const void *key, const byte outlen,
ashleymills 0:714293de3836 380 const word64 inlen, byte keylen )
ashleymills 0:714293de3836 381 {
ashleymills 0:714293de3836 382 blake2b_state S[1];
ashleymills 0:714293de3836 383
ashleymills 0:714293de3836 384 /* Verify parameters */
ashleymills 0:714293de3836 385 if ( NULL == in ) return -1;
ashleymills 0:714293de3836 386
ashleymills 0:714293de3836 387 if ( NULL == out ) return -1;
ashleymills 0:714293de3836 388
ashleymills 0:714293de3836 389 if( NULL == key ) keylen = 0;
ashleymills 0:714293de3836 390
ashleymills 0:714293de3836 391 if( keylen > 0 )
ashleymills 0:714293de3836 392 {
ashleymills 0:714293de3836 393 if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
ashleymills 0:714293de3836 394 }
ashleymills 0:714293de3836 395 else
ashleymills 0:714293de3836 396 {
ashleymills 0:714293de3836 397 if( blake2b_init( S, outlen ) < 0 ) return -1;
ashleymills 0:714293de3836 398 }
ashleymills 0:714293de3836 399
ashleymills 0:714293de3836 400 blake2b_update( S, ( byte * )in, inlen );
ashleymills 0:714293de3836 401 blake2b_final( S, out, outlen );
ashleymills 0:714293de3836 402 return 0;
ashleymills 0:714293de3836 403 }
ashleymills 0:714293de3836 404
ashleymills 0:714293de3836 405 #if defined(BLAKE2B_SELFTEST)
ashleymills 0:714293de3836 406 #include <string.h>
ashleymills 0:714293de3836 407 #include "blake2-kat.h"
ashleymills 0:714293de3836 408 int main( int argc, char **argv )
ashleymills 0:714293de3836 409 {
ashleymills 0:714293de3836 410 byte key[BLAKE2B_KEYBYTES];
ashleymills 0:714293de3836 411 byte buf[KAT_LENGTH];
ashleymills 0:714293de3836 412
ashleymills 0:714293de3836 413 for( word32 i = 0; i < BLAKE2B_KEYBYTES; ++i )
ashleymills 0:714293de3836 414 key[i] = ( byte )i;
ashleymills 0:714293de3836 415
ashleymills 0:714293de3836 416 for( word32 i = 0; i < KAT_LENGTH; ++i )
ashleymills 0:714293de3836 417 buf[i] = ( byte )i;
ashleymills 0:714293de3836 418
ashleymills 0:714293de3836 419 for( word32 i = 0; i < KAT_LENGTH; ++i )
ashleymills 0:714293de3836 420 {
ashleymills 0:714293de3836 421 byte hash[BLAKE2B_OUTBYTES];
ashleymills 0:714293de3836 422 blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
ashleymills 0:714293de3836 423
ashleymills 0:714293de3836 424 if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
ashleymills 0:714293de3836 425 {
ashleymills 0:714293de3836 426 puts( "error" );
ashleymills 0:714293de3836 427 return -1;
ashleymills 0:714293de3836 428 }
ashleymills 0:714293de3836 429 }
ashleymills 0:714293de3836 430
ashleymills 0:714293de3836 431 puts( "ok" );
ashleymills 0:714293de3836 432 return 0;
ashleymills 0:714293de3836 433 }
ashleymills 0:714293de3836 434 #endif
ashleymills 0:714293de3836 435
ashleymills 0:714293de3836 436
ashleymills 0:714293de3836 437 /* CTaoCrypt API */
ashleymills 0:714293de3836 438
ashleymills 0:714293de3836 439 /* Init Blake2b digest, track size incase final doesn't want to "remember" */
ashleymills 0:714293de3836 440 int InitBlake2b(Blake2b* b2b, word32 digestSz)
ashleymills 0:714293de3836 441 {
ashleymills 0:714293de3836 442 b2b->digestSz = digestSz;
ashleymills 0:714293de3836 443
ashleymills 0:714293de3836 444 return blake2b_init(b2b->S, (byte)digestSz);
ashleymills 0:714293de3836 445 }
ashleymills 0:714293de3836 446
ashleymills 0:714293de3836 447
ashleymills 0:714293de3836 448 /* Blake2b Update */
ashleymills 0:714293de3836 449 int Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz)
ashleymills 0:714293de3836 450 {
ashleymills 0:714293de3836 451 return blake2b_update(b2b->S, data, sz);
ashleymills 0:714293de3836 452 }
ashleymills 0:714293de3836 453
ashleymills 0:714293de3836 454
ashleymills 0:714293de3836 455 /* Blake2b Final, if pass in zero size we use init digestSz */
ashleymills 0:714293de3836 456 int Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz)
ashleymills 0:714293de3836 457 {
ashleymills 0:714293de3836 458 word32 sz = requestSz ? requestSz : b2b->digestSz;
ashleymills 0:714293de3836 459
ashleymills 0:714293de3836 460 return blake2b_final(b2b->S, final, (byte)sz);
ashleymills 0:714293de3836 461 }
ashleymills 0:714293de3836 462
ashleymills 0:714293de3836 463
ashleymills 0:714293de3836 464 /* end CTaoCrypt API */
ashleymills 0:714293de3836 465
ashleymills 0:714293de3836 466 #endif /* HAVE_BLAKE2 */
ashleymills 0:714293de3836 467