d5e5e2ffaf
Move digest code into the relevant providers (fips, default, legacy). The headers are temporarily moved to be internal, and will be moved into providers after all external references are resolved. The deprecated digest code can not be removed until EVP_PKEY (signing) is supported by providers. EVP_MD data can also not yet be cleaned up for the same reasons. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8763)
106 lines
2.6 KiB
C
106 lines
2.6 KiB
C
/*
|
|
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "internal/sha3.h"
|
|
|
|
void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
|
|
|
|
void sha3_reset(KECCAK1600_CTX *ctx)
|
|
{
|
|
memset(ctx->A, 0, sizeof(ctx->A));
|
|
ctx->bufsz = 0;
|
|
}
|
|
|
|
int sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen)
|
|
{
|
|
size_t bsz = SHA3_BLOCKSIZE(bitlen);
|
|
|
|
if (bsz <= sizeof(ctx->buf)) {
|
|
sha3_reset(ctx);
|
|
ctx->block_size = bsz;
|
|
ctx->md_size = bitlen / 8;
|
|
ctx->pad = pad;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int keccak_kmac_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen)
|
|
{
|
|
int ret = sha3_init(ctx, pad, bitlen);
|
|
|
|
if (ret)
|
|
ctx->md_size *= 2;
|
|
return ret;
|
|
}
|
|
|
|
int sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len)
|
|
{
|
|
const unsigned char *inp = _inp;
|
|
size_t bsz = ctx->block_size;
|
|
size_t num, rem;
|
|
|
|
if (len == 0)
|
|
return 1;
|
|
|
|
if ((num = ctx->bufsz) != 0) { /* process intermediate buffer? */
|
|
rem = bsz - num;
|
|
|
|
if (len < rem) {
|
|
memcpy(ctx->buf + num, inp, len);
|
|
ctx->bufsz += len;
|
|
return 1;
|
|
}
|
|
/*
|
|
* We have enough data to fill or overflow the intermediate
|
|
* buffer. So we append |rem| bytes and process the block,
|
|
* leaving the rest for later processing...
|
|
*/
|
|
memcpy(ctx->buf + num, inp, rem);
|
|
inp += rem, len -= rem;
|
|
(void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
|
|
ctx->bufsz = 0;
|
|
/* ctx->buf is processed, ctx->num is guaranteed to be zero */
|
|
}
|
|
|
|
if (len >= bsz)
|
|
rem = SHA3_absorb(ctx->A, inp, len, bsz);
|
|
else
|
|
rem = len;
|
|
|
|
if (rem) {
|
|
memcpy(ctx->buf, inp + len - rem, rem);
|
|
ctx->bufsz = rem;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int sha3_final(unsigned char *md, KECCAK1600_CTX *ctx)
|
|
{
|
|
size_t bsz = ctx->block_size;
|
|
size_t num = ctx->bufsz;
|
|
|
|
/*
|
|
* Pad the data with 10*1. Note that |num| can be |bsz - 1|
|
|
* in which case both byte operations below are performed on
|
|
* same byte...
|
|
*/
|
|
memset(ctx->buf + num, 0, bsz - num);
|
|
ctx->buf[num] = ctx->pad;
|
|
ctx->buf[bsz - 1] |= 0x80;
|
|
|
|
(void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
|
|
|
|
SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
|
|
|
|
return 1;
|
|
}
|