int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) { if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; const blake2b_param P = { outlen, keylen, 1, 1, 0, 0, 0, 0, {0}, {0}, {0} }; if( blake2b_init_param( S, &P ) < 0 ) return 0; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; }
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) { /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; const blake2s_param P = { outlen, keylen, 1, 1, 0, {0}, 0, 0, {0}, {0} }; 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; }
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) { blake2s_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; P->digest_length = outlen; P->key_length = keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store48( &P->node_offset, 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; }
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) { if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; if( blake2bp_init_root( S->R, outlen, keylen ) < 0 ) return -1; for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; }
int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key, const byte keylen ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; 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 ) ); if( blake2b_init_param( S, P ) < 0 ) return -1; { #ifdef WOLFSSL_SMALL_STACK byte* block; block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER); if ( block == NULL ) return -1; #else byte block[BLAKE2B_BLOCKBYTES]; #endif XMEMSET( block, 0, BLAKE2B_BLOCKBYTES ); XMEMCPY( block, key, keylen ); blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */ /* memory */ #ifdef WOLFSSL_SMALL_STACK XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif } return 0; }
int blake2b_init_key_salt_personal( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen, const void *salt, const void *personal ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; 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; memset( P->reserved, 0, sizeof( P->reserved ) ); if (salt != NULL) { blake2b_param_set_salt( P, (const uint8_t *) salt ); } else { memset( P->salt, 0, sizeof( P->salt ) ); } if (personal != NULL) { blake2b_param_set_personal( P, (const uint8_t *) personal ); } else { memset( P->personal, 0, sizeof( P->personal ) ); } if( blake2b_init_param( S, P ) < 0 ) return -1; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; }
int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ) { if ( outlen == 0 || outlen > 0xFFFFUL ) { return -1; } if (NULL != key && keylen > BLAKE2B_KEYBYTES) { return -1; } if (NULL == key && keylen > 0) { return -1; } /* Initialize parameter block */ S->P->digest_length = BLAKE2S_OUTBYTES; S->P->key_length = keylen; S->P->fanout = 1; S->P->depth = 1; store32( &S->P->leaf_length, 0 ); store32( &S->P->node_offset, 0 ); store16( &S->P->xof_length, outlen ); S->P->node_depth = 0; S->P->inner_length = 0; memset( S->P->salt, 0, sizeof( S->P->salt ) ); memset( S->P->personal, 0, sizeof( S->P->personal ) ); if( blake2s_init_param( S->S, S->P ) < 0 ) { return -1; } if (keylen > 0) { uint8_t block[BLAKE2S_BLOCKBYTES]; memset(block, 0, BLAKE2S_BLOCKBYTES); memcpy(block, key, keylen); blake2s_update(S->S, block, BLAKE2S_BLOCKBYTES); secure_zero_memory(block, BLAKE2S_BLOCKBYTES); } return 0; }
int blake2b_final( blake2b_state *S, void *out, size_t outlen ) { uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; size_t i; if( out == NULL || outlen < S->outlen ) return -1; if( blake2b_is_lastblock( S ) ) return -1; blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S ); memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ blake2b_compress( S, S->buf ); 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, S->outlen ); secure_zero_memory(buffer, sizeof(buffer)); return 0; }
static PyObject * py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, Py_buffer *key, Py_buffer *salt, Py_buffer *person, int fanout, int depth, unsigned long leaf_size, unsigned long long node_offset, int node_depth, int inner_size, int last_node) /*[clinic end generated code: output=b95806be0514dcf7 input=f18d6efd9b9a1271]*/ { BLAKE2sObject *self = NULL; Py_buffer buf; self = new_BLAKE2sObject(type); if (self == NULL) { goto error; } /* Zero parameter block. */ memset(&self->param, 0, sizeof(self->param)); /* Set digest size. */ if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) { PyErr_Format(PyExc_ValueError, "digest_size must be between 1 and %d bytes", BLAKE2S_OUTBYTES); goto error; } self->param.digest_length = digest_size; /* Set salt parameter. */ if ((salt->obj != NULL) && salt->len) { if (salt->len > BLAKE2S_SALTBYTES) { PyErr_Format(PyExc_ValueError, "maximum salt length is %d bytes", BLAKE2S_SALTBYTES); goto error; } memcpy(self->param.salt, salt->buf, salt->len); } /* Set personalization parameter. */ if ((person->obj != NULL) && person->len) { if (person->len > BLAKE2S_PERSONALBYTES) { PyErr_Format(PyExc_ValueError, "maximum person length is %d bytes", BLAKE2S_PERSONALBYTES); goto error; } memcpy(self->param.personal, person->buf, person->len); } /* Set tree parameters. */ if (fanout < 0 || fanout > 255) { PyErr_SetString(PyExc_ValueError, "fanout must be between 0 and 255"); goto error; } self->param.fanout = (uint8_t)fanout; if (depth <= 0 || depth > 255) { PyErr_SetString(PyExc_ValueError, "depth must be between 1 and 255"); goto error; } self->param.depth = (uint8_t)depth; if (leaf_size > 0xFFFFFFFFU) { PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); goto error; } // NB: Simple assignment here would be incorrect on big endian platforms. store32(&(self->param.leaf_length), leaf_size); #ifdef HAVE_BLAKE2S if (node_offset > 0xFFFFFFFFFFFFULL) { /* maximum 2**48 - 1 */ PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); goto error; } store48(&(self->param.node_offset), node_offset); #else // NB: Simple assignment here would be incorrect on big endian platforms. store64(&(self->param.node_offset), node_offset); #endif if (node_depth < 0 || node_depth > 255) { PyErr_SetString(PyExc_ValueError, "node_depth must be between 0 and 255"); goto error; } self->param.node_depth = node_depth; if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) { PyErr_Format(PyExc_ValueError, "inner_size must be between 0 and is %d", BLAKE2S_OUTBYTES); goto error; } self->param.inner_length = inner_size; /* Set key length. */ if ((key->obj != NULL) && key->len) { if (key->len > BLAKE2S_KEYBYTES) { PyErr_Format(PyExc_ValueError, "maximum key length is %d bytes", BLAKE2S_KEYBYTES); goto error; } self->param.key_length = (uint8_t)key->len; } /* Initialize hash state. */ if (blake2s_init_param(&self->state, &self->param) < 0) { PyErr_SetString(PyExc_RuntimeError, "error initializing hash state"); goto error; } /* Set last node flag (must come after initialization). */ self->state.last_node = last_node; /* Process key block if any. */ if (self->param.key_length) { uint8_t block[BLAKE2S_BLOCKBYTES]; memset(block, 0, sizeof(block)); memcpy(block, key->buf, key->len); blake2s_update(&self->state, block, sizeof(block)); secure_zero_memory(block, sizeof(block)); } /* Process initial data if any. */ if (data != NULL) { GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); if (buf.len >= HASHLIB_GIL_MINSIZE) { Py_BEGIN_ALLOW_THREADS blake2s_update(&self->state, buf.buf, buf.len); Py_END_ALLOW_THREADS } else {
ERL_NIF_TERM blake2bp_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[1]; ErlNifBinary input, key, salt, personal; uint8_t out[BLAKE2B_OUTBYTES] = {0}; unsigned int outlen; int i; ERL_NIF_TERM tmphash[BLAKE2B_OUTBYTES]; if (argc != 5 || !enif_inspect_binary(env, argv[0], &input) || !enif_inspect_binary(env, argv[1], &key) || !enif_get_uint(env, argv[2], &outlen) || !enif_inspect_binary(env, argv[3], &salt) || !enif_inspect_binary(env, argv[4], &personal)) return enif_make_badarg(env); if (!outlen || outlen > BLAKE2B_OUTBYTES) return -1; if( key.size > BLAKE2B_KEYBYTES ) return -1; for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, key.size, i, salt.data, personal.data, salt.size, personal.size) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node if( key.size > 0 ) { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key.data, key.size ); for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) #endif { #if defined(_OPENMP) size_t id__ = omp_get_thread_num(); #endif uint64_t inlen__ = input.size; const uint8_t *in__ = ( const uint8_t * )input.data; in__ += id__ * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) { const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; blake2b_update( S[id__], in__, len ); } blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, key.size, salt.data, personal.data, salt.size, personal.size) < 0 ) return -1; FS->last_node = 1; // Mark as last node for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); blake2b_final( FS, out, outlen );; for (i = 0; i < outlen; i++) { tmphash[i] = enif_make_uint(env, out[i]); } return enif_make_list_from_array(env, tmphash, outlen); }
int blake2bp( uint8_t *out, const void *in, const void *key, uint8_t outlen, uint64_t inlen, uint8_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[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 > BLAKE2B_OUTBYTES ) return -1; if( keylen > BLAKE2B_KEYBYTES ) return -1; for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ if( keylen > 0 ) { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) #endif { #if defined(_OPENMP) size_t id__ = omp_get_thread_num(); #endif uint64_t inlen__ = inlen; const uint8_t *in__ = ( const uint8_t * )in; in__ += id__ * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) { const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; blake2b_update( S[id__], in__, len ); } blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, keylen ) < 0 ) return -1; FS->last_node = 1; /* Mark as last node */ for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); return blake2b_final( FS, out, outlen );; }