void hmac_keccak_finish(hmac_keccak_state *S, uint8_t *digest) { uint8_t ihash[HASH_SIZE]; keccak_finish(&S->inner, ihash); keccak_update(&S->outer, ihash, HASH_SIZE); keccak_finish(&S->outer, digest); memwipe(ihash, HASH_SIZE); }
EXPORT_SYM int keccak_squeeze (keccak_state *self, uint8_t *out, size_t length) { if ((NULL == self) || (NULL == out)) return ERR_NULL; if (!self->squeezing) { keccak_finish (self); } assert(self->valid_bytes > 0); assert(self->valid_bytes <= self->rate); while (length > 0) { unsigned bytestocopy; bytestocopy = minAB(self->valid_bytes, length); memcpy(out, self->buf + (self->rate - self->valid_bytes), bytestocopy); self->valid_bytes -= bytestocopy; out += bytestocopy; length -= bytestocopy; if (self->valid_bytes == 0) { keccak_function (self->state); keccak_squeeze_internal (self); self->valid_bytes = self->rate; } } return 0; }