/* Is this correct? */ int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) { uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; if( outlen > BLAKE2B_OUTBYTES ) return -1; if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); S->buflen -= BLAKE2B_BLOCKBYTES; memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); } blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S ); memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ blake2b_compress( S, S->buf ); for( int 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 ); return 0; }
int blake2b_update( blake2b_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 = BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */ blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); /* Compress */ in += fill; inlen -= fill; while(inlen > BLAKE2B_BLOCKBYTES) { blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress( S, in ); in += BLAKE2B_BLOCKBYTES; inlen -= BLAKE2B_BLOCKBYTES; } } memcpy( S->buf + S->buflen, in, inlen ); S->buflen += inlen; } return 0; }
int blake2b_process(hash_state *md, const unsigned char *in, unsigned long inlen) { LTC_ARGCHK(md != NULL); LTC_ARGCHK(in != NULL); if (md->blake2b.curlen > sizeof(md->blake2b.buf)) { return CRYPT_INVALID_ARG; } if (inlen > 0) { unsigned long left = md->blake2b.curlen; unsigned long fill = BLAKE2B_BLOCKBYTES - left; if (inlen > fill) { md->blake2b.curlen = 0; XMEMCPY(md->blake2b.buf + left, in, fill); /* Fill buffer */ blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES); blake2b_compress(md, md->blake2b.buf); /* Compress */ in += fill; inlen -= fill; while (inlen > BLAKE2B_BLOCKBYTES) { blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES); blake2b_compress(md, in); in += BLAKE2B_BLOCKBYTES; inlen -= BLAKE2B_BLOCKBYTES; } } XMEMCPY(md->blake2b.buf + md->blake2b.curlen, in, inlen); md->blake2b.curlen += inlen; } return CRYPT_OK; }
/* Is this correct? */ int blake2b_final( blake2b_state *S, byte *out, byte outlen ) { byte buffer[BLAKE2B_OUTBYTES]; int i; if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); if ( blake2b_compress( S, S->buf ) < 0 ) return -1; S->buflen -= BLAKE2B_BLOCKBYTES; XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (wolfssl_word)S->buflen ); } blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S ); XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) ); /* Padding */ if ( blake2b_compress( S, S->buf ) < 0 ) return -1; for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); XMEMCPY( out, buffer, outlen ); return 0; }
/* * Calculate the final hash and save it in md. * Always returns 1. */ int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c) { uint8_t outbuffer[BLAKE2B_OUTBYTES] = {0}; uint8_t *target = outbuffer; int iter = (c->outlen + 7) / 8; int i; /* Avoid writing to the temporary buffer if possible */ if ((c->outlen % sizeof(c->h[0])) == 0) target = md; blake2b_set_lastblock(c); /* Padding */ memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen); blake2b_compress(c, c->buf, c->buflen); /* Output full hash to buffer */ for (i = 0; i < iter; ++i) store64(target + sizeof(c->h[i]) * i, c->h[i]); if (target != md) memcpy(md, target, c->outlen); OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX)); return 1; }
int blake2b_done(hash_state *md, unsigned char *out) { unsigned char buffer[BLAKE2B_OUTBYTES] = { 0 }; unsigned long i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); /* if(md->blakebs.outlen != outlen) return CRYPT_INVALID_ARG; */ if (blake2b_is_lastblock(md)) return CRYPT_ERROR; blake2b_increment_counter(md, md->blake2b.curlen); blake2b_set_lastblock(md); XMEMSET(md->blake2b.buf + md->blake2b.curlen, 0, BLAKE2B_BLOCKBYTES - md->blake2b.curlen); /* Padding */ blake2b_compress(md, md->blake2b.buf); for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */ STORE64L(md->blake2b.h[i], buffer + i * 8); XMEMCPY(out, buffer, md->blake2b.outlen); zeromem(md, sizeof(hash_state)); #ifdef LTC_CLEAN_STACK zeromem(buffer, sizeof(buffer)); #endif return CRYPT_OK; }
void blake2b_final(struct blake2b *B, void *digest) { uint8_t *d = digest; unsigned dlen = B->dlen; unsigned i; /* Pad with zeros, and do the last compression. */ B->c += B->nb; for (i = B->nb; i < 128; i++) B->b[i] = 0; blake2b_compress(B->h, B->c, ~(uint64_t)0, B->b); /* Reveal the first dlen/8 words of the state. */ for (i = 0; i < dlen/8; i++) le64enc(d + 8*i, B->h[i]); d += 8*i; dlen -= 8*i; /* If the caller wants a partial word, reveal that too. */ if (dlen) { uint64_t hi = B->h[i]; do { *d++ = hi; hi >>= 8; } while (--dlen); } /* Erase the state. */ (void)blake2b_explicit_memset(B, 0, sizeof B); }
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) { while( inlen > 0 ) { size_t left = S->buflen; size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { memcpy( S->buf + left, in, fill ); // Fill buffer S->buflen += fill; blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); // Compress memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left S->buflen -= BLAKE2B_BLOCKBYTES; in += fill; inlen -= fill; } else // inlen <= fill { memcpy( S->buf + left, in, inlen ); S->buflen += inlen; // Be lazy, do not compress in += inlen; inlen -= inlen; } } return 0; }
int blake2b_final(blake2b_state *S, void *out, size_t outlen) { uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; unsigned int i; /* Sanity checks */ if (S == NULL || out == NULL || outlen < S->outlen) { return -1; } /* Is this a reused state? */ if (S->f[0] != 0) { 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); burn(buffer, sizeof(buffer)); burn(S->buf, sizeof(S->buf)); burn(S->h, sizeof(S->h)); return 0; }
/* inlen now in bytes */ int blake2b_update( blake2b_state *S, const byte *in, word64 inlen ) { while( inlen > 0 ) { word64 left = S->buflen; word64 fill = 2 * BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */ S->buflen += fill; blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); if ( blake2b_compress( S, S->buf ) < 0 ) return -1; /* Compress */ XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ S->buflen -= BLAKE2B_BLOCKBYTES; in += fill; inlen -= fill; } else /* inlen <= fill */ { XMEMCPY( S->buf + left, in, (wolfssl_word)inlen ); S->buflen += inlen; /* Be lazy, do not compress */ in += inlen; inlen -= inlen; } } return 0; }
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) { if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); S->buflen -= BLAKE2B_BLOCKBYTES; memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); } blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S ); memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ blake2b_compress( S, S->buf ); memcpy( out, &S->h[0], outlen ); return 0; }
/* Absorb the input data into the hash state. Always returns 1. */ int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen) { const uint8_t *in = data; size_t fill; /* * Intuitively one would expect intermediate buffer, c->buf, to * store incomplete blocks. But in this case we are interested to * temporarily stash even complete blocks, because last one in the * stream has to be treated in special way, and at this point we * don't know if last block in *this* call is last one "ever". This * is the reason for why |datalen| is compared as >, and not >=. */ fill = sizeof(c->buf) - c->buflen; if (datalen > fill) { if (c->buflen) { memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */ blake2b_compress(c, c->buf, BLAKE2B_BLOCKBYTES); c->buflen = 0; in += fill; datalen -= fill; } if (datalen > BLAKE2B_BLOCKBYTES) { size_t stashlen = datalen % BLAKE2B_BLOCKBYTES; /* * If |datalen| is a multiple of the blocksize, stash * last complete block, it can be final one... */ stashlen = stashlen ? stashlen : BLAKE2B_BLOCKBYTES; datalen -= stashlen; blake2b_compress(c, in, datalen); in += datalen; datalen = stashlen; } } assert(datalen <= BLAKE2B_BLOCKBYTES); memcpy(c->buf + c->buflen, in, datalen); c->buflen += datalen; /* Be lazy, do not compress */ return 1; }
int blake2b_update(blake2b_state *S, const void *in, size_t inlen) { const uint8_t *pin = (const uint8_t *)in; /* Complete current block */ memcpy(&S->buf[4], pin, 124); blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress(S, S->buf); S->buflen = 0; pin += 124; register int8_t i = 7; /* Avoid buffer copies when possible */ while (i--) { blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress(S, pin); pin += BLAKE2B_BLOCKBYTES; } memcpy(&S->buf[S->buflen], pin, 4); S->buflen += 4; return 0; }
int blake2b_update(blake2b_state *S, const void *in, size_t inlen) { const uint8_t *pin = (const uint8_t *)in; if (inlen == 0) { return 0; } /* Sanity check */ if (S == NULL || in == NULL) { return -1; } /* Is this a reused state? */ if (S->f[0] != 0) { return -1; } if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) { /* Complete current block */ size_t left = S->buflen; size_t fill = BLAKE2B_BLOCKBYTES - left; memcpy(&S->buf[left], pin, fill); blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress(S, S->buf); S->buflen = 0; inlen -= fill; pin += fill; /* Avoid buffer copies when possible */ while (inlen > BLAKE2B_BLOCKBYTES) { blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress(S, pin); inlen -= BLAKE2B_BLOCKBYTES; pin += BLAKE2B_BLOCKBYTES; } } memcpy(&S->buf[S->buflen], pin, inlen); S->buflen += (unsigned int)inlen; return 0; }
void blake2b_update(struct blake2b *B, const void *buf, size_t len) { const uint8_t *p = buf; size_t n = len; /* Check the current state of the buffer. */ if (n <= 128u - B->nb) { /* Can at most exactly fill the buffer. */ (void)memcpy(&B->b[B->nb], p, n); B->nb += n; return; } else if (0 < B->nb) { /* Can fill the buffer and go on. */ (void)memcpy(&B->b[B->nb], p, 128 - B->nb); B->c += 128; blake2b_compress(B->h, B->c, 0, B->b); p += 128 - B->nb; n -= 128 - B->nb; } /* At a block boundary. Compress straight from the input. */ while (128 < n) { B->c += 128; blake2b_compress(B->h, B->c, 0, p); p += 128; n -= 128; } /* * Put whatever's left in the buffer. We may fill the buffer, * but we can't compress in that case until we know whether we * are compressing the last block or not. */ (void)memcpy(B->b, p, n); B->nb = n; }
void blake2b_update(blake2b_ctx *ctx, const void *in, size_t inlen) // data bytes { size_t i; for (i = 0; i < inlen; i++) { if (ctx->c == 128) { // buffer full ? ctx->t[0] += ctx->c; // add counters if (ctx->t[0] < ctx->c) // carry overflow ? ctx->t[1]++; // high word blake2b_compress(ctx, 0); // compress (not last) ctx->c = 0; // counter to zero } ctx->b[ctx->c++] = ((const uint8_t *) in)[i]; } }
/* update with new data */ static void blake2b_update( blake2b_ctx * ctx, const void * in, HB_SIZE inlen ) /* data bytes */ { HB_SIZE i; for( i = 0; i < inlen; i++ ) { if( ctx->c == 128 ) /* buffer full ? */ { ctx->t[ 0 ] += ctx->c; /* add counters */ if( ctx->t[ 0 ] < ctx->c ) /* carry overflow ? */ ctx->t[ 1 ]++; /* high word */ blake2b_compress( ctx, 0 ); /* compress (not last) */ ctx->c = 0; /* counter to zero */ } ctx->b[ ctx->c++ ] = ( ( const HB_U8 * ) in )[ i ]; } }
void blake2b_final(blake2b_ctx *ctx, void *out) { size_t i; ctx->t[0] += ctx->c; // mark last block offset if (ctx->t[0] < ctx->c) // carry overflow ctx->t[1]++; // high word while (ctx->c < 128) // fill up with zeros ctx->b[ctx->c++] = 0; blake2b_compress(ctx, 1); // final block flag = 1 // little endian convert and store for (i = 0; i < ctx->outlen; i++) { ((uint8_t *) out)[i] = (ctx->h[i >> 3] >> (8 * (i & 7))) & 0xFF; } }
/* finalize */ static void blake2b_final( blake2b_ctx * ctx, void * out ) { HB_SIZE i; ctx->t[ 0 ] += ctx->c; /* mark last block offset */ if( ctx->t[ 0 ] < ctx->c ) /* carry overflow */ ctx->t[ 1 ]++; /* high word */ while( ctx->c < 128 ) /* fill up with zeros */ ctx->b[ ctx->c++ ] = 0; blake2b_compress( ctx, 1 ); /* final block flag = 1 */ /* little endian convert and store */ for( i = 0; i < ctx->outlen; i++ ) { ( ( HB_U8 * ) out )[ i ] = ( ctx->h[ i >> 3 ] >> ( 8 * ( i & 7 ) ) ) & 0xFF; } }
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; }