void blake2sp_init( blake2sp_state *S ) { memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; blake2s_init_param( S->R, 0, 1 ); // Init root. for( uint i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_init_param( S->S[i], i, 0 ); // Init leaf. S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; }
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 blake2xs_final(blake2xs_state *S, void *out, size_t outlen) { blake2s_state C[1]; blake2s_param P[1]; uint16_t xof_length = load16(&S->P->xof_length); uint8_t root[BLAKE2S_BLOCKBYTES]; size_t i; if (NULL == out) { return -1; } /* outlen must match the output size defined in xof_length, */ /* unless it was -1, in which case anything goes except 0. */ if(xof_length == 0xFFFFUL) { if(outlen == 0) { return -1; } } else { if(outlen != xof_length) { return -1; } } /* Finalize the root hash */ if (blake2s_final(S->S, root, BLAKE2S_OUTBYTES) < 0) { return -1; } /* Set common block structure values */ /* Copy values from parent instance, and only change the ones below */ memcpy(P, S->P, sizeof(blake2s_param)); P->key_length = 0; P->fanout = 0; P->depth = 0; store32(&P->leaf_length, BLAKE2S_OUTBYTES); P->inner_length = BLAKE2S_OUTBYTES; P->node_depth = 0; for (i = 0; outlen > 0; ++i) { const size_t block_size = (outlen < BLAKE2S_OUTBYTES) ? outlen : BLAKE2S_OUTBYTES; /* Initialize state */ P->digest_length = block_size; store32(&P->node_offset, i); blake2s_init_param(C, P); /* Process key if needed */ blake2s_update(C, root, BLAKE2S_OUTBYTES); if (blake2s_final(C, (uint8_t *)out + i * BLAKE2S_OUTBYTES, block_size) < 0) { return -1; } outlen -= block_size; } secure_zero_memory(root, sizeof(root)); secure_zero_memory(P, sizeof(P)); secure_zero_memory(C, sizeof(C)); /* Put blake2xs in an invalid state? cf. blake2s_is_lastblock */ return 0; }
static inline int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen ) { blake2s_param P[1]; P->digest_length = outlen; P->key_length = keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; store32( &P->leaf_length, 0 ); store48( P->node_offset, 0ULL ); P->node_depth = 1; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); }
BLAKE2_LOCAL_INLINE(int) blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) { blake2s_param P[1]; P->digest_length = outlen; P->key_length = keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; store48( P->node_offset, offset ); P->node_depth = 0; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); }
/* Initialize the hashing context. Always returns 1. */ int BLAKE2s_Init(BLAKE2S_CTX *c) { BLAKE2S_PARAM P[1]; P->digest_length = BLAKE2S_DIGEST_LENGTH; P->key_length = 0; 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->salt, 0, sizeof(P->salt)); memset(P->personal, 0, sizeof(P->personal)); blake2s_init_param(c, P); return 1; }
/* Some sort of default parameter block initialization, for sequential blake2s */ int blake2s_init( blake2s_state *S, const uint8_t outlen ) { const blake2s_param P = { outlen, 0, 1, 1, 0, {0}, 0, 0, {0}, {0} }; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; return blake2s_init_param( S, &P ); }
// Sequential blake2s initialization int blake2s_init( blake2s_state *S, const uint8_t outlen ) { blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; P->digest_length = outlen; P->key_length = 0; 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 ) ); return blake2s_init_param( S, P ); }
/* Sequential blake2s initialization */ int blake2s_Init( blake2s_state *S, size_t outlen ) { blake2s_param P[1]; 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 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; }
static inline int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen, const void *salt, const void *personal, const uint8_t saltlen, const uint8_t personallen ) { blake2s_param P[1]; P->digest_length = outlen; P->key_length = keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; store32( &P->leaf_length, 0 ); store48( P->node_offset, 0ULL ); P->node_depth = 1; P->inner_length = BLAKE2S_OUTBYTES; if (saltlen) memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); else memset(P->salt, 0, sizeof( P->salt )); if (personallen) memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); else memset(P->personal, 0, sizeof(P->personal)); return blake2s_init_param( S, P ); }
int blake2s_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen) { unsigned char P[BLAKE2S_PARAM_SIZE]; int err; LTC_ARGCHK(md != NULL); if ((!outlen) || (outlen > BLAKE2S_OUTBYTES)) return CRYPT_INVALID_ARG; if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES)) return CRYPT_INVALID_ARG; XMEMSET(P, 0, sizeof(P)); P[O_DIGEST_LENGTH] = (unsigned char)outlen; P[O_KEY_LENGTH] = (unsigned char)keylen; P[O_FANOUT] = 1; P[O_DEPTH] = 1; err = blake2s_init_param(md, P); if (err != CRYPT_OK) return err; if (key) { unsigned char block[BLAKE2S_BLOCKBYTES]; XMEMSET(block, 0, BLAKE2S_BLOCKBYTES); XMEMCPY(block, key, keylen); blake2s_process(md, block, BLAKE2S_BLOCKBYTES); #ifdef LTC_CLEAN_STACK zeromem(block, sizeof(block)); #endif } return CRYPT_OK; }
int blake2s_init( blake2s_state *S, const uint8_t outlen, const void *salt, const void *personal, const uint8_t saltlen, const uint8_t personallen) { blake2s_param P[1]; P->digest_length = outlen; P->key_length = 0; 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) ); if (saltlen) memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); else memset(P->salt, 0, sizeof( P->salt )); if (personallen) memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); else memset(P->personal, 0, sizeof(P->personal)); return blake2s_init_param( S, P ); }
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 {
/* blake2sp_init_param defaults to setting the expecting output length from the digest_length parameter block field. In some cases, however, we do not want this, as the output length of these instances is given by inner_length instead. */ static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) { int err = blake2s_init_param(S, P); S->outlen = P->inner_length; return err; }