ret_t sha()

in src/random/sha.c [124:168]


ret_t sha(OUT sha_dgst_t *dgst, IN const uint32_t byte_len, IN const uint8_t *msg)
{
  uint64_t       i;
  uint32_t       last_len;
  const uint64_t encoded_len             = bswap_64((uint64_t)byte_len * 8);
  const uint64_t tmp[SHA512_DGST_QWORDS] = INIT_HASH;
  sha512_dgst_t  _dgst;
  bike_memcpy(_dgst.u.raw, (const uint8_t *)tmp, sizeof(_dgst));

  uint8_t last_block[(2 * HASH_BLOCK_BYTES)];

  if((NULL == dgst) || (NULL == msg)) {
    return FAIL;
  }

  if((byte_len % HASH_BLOCK_BYTES) < 112) {
    last_len = HASH_BLOCK_BYTES;
  } else {
    last_len = (2 * HASH_BLOCK_BYTES);
  }

  for(i = 0; i < (byte_len % HASH_BLOCK_BYTES); i++) {
    last_block[i] = msg[(byte_len / HASH_BLOCK_BYTES) * HASH_BLOCK_BYTES + i];
  }

  last_block[i++] = 0x80;

  for(; i < (last_len - 8); i++) {
    last_block[i] = 0;
  }

  bike_memcpy(&last_block[last_len - 8], &encoded_len, sizeof(encoded_len));

  GUARD(sha_update(&_dgst, msg, byte_len / HASH_BLOCK_BYTES));
  GUARD(sha_update(&_dgst, last_block, last_len / HASH_BLOCK_BYTES));

  for(i = 0; i < (sizeof(sha_dgst_t) / 8); i++) {
    dgst->u.qw[i] = bswap_64(_dgst.u.qw[i]);
  }

  secure_clean(_dgst.u.raw, sizeof(_dgst));
  secure_clean(last_block, sizeof(last_block));

  return SUCCESS;
}