1/* 2 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#include <string.h> 11#include "internal/sha3.h" 12 13void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r); 14 15void ossl_sha3_reset(KECCAK1600_CTX *ctx) 16{ 17 memset(ctx->A, 0, sizeof(ctx->A)); 18 ctx->bufsz = 0; 19} 20 21int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen) 22{ 23 size_t bsz = SHA3_BLOCKSIZE(bitlen); 24 25 if (bsz <= sizeof(ctx->buf)) { 26 ossl_sha3_reset(ctx); 27 ctx->block_size = bsz; 28 ctx->md_size = bitlen / 8; 29 ctx->pad = pad; 30 return 1; 31 } 32 33 return 0; 34} 35 36int ossl_keccak_kmac_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen) 37{ 38 int ret = ossl_sha3_init(ctx, pad, bitlen); 39 40 if (ret) 41 ctx->md_size *= 2; 42 return ret; 43} 44 45int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len) 46{ 47 const unsigned char *inp = _inp; 48 size_t bsz = ctx->block_size; 49 size_t num, rem; 50 51 if (len == 0) 52 return 1; 53 54 if ((num = ctx->bufsz) != 0) { /* process intermediate buffer? */ 55 rem = bsz - num; 56 57 if (len < rem) { 58 memcpy(ctx->buf + num, inp, len); 59 ctx->bufsz += len; 60 return 1; 61 } 62 /* 63 * We have enough data to fill or overflow the intermediate 64 * buffer. So we append |rem| bytes and process the block, 65 * leaving the rest for later processing... 66 */ 67 memcpy(ctx->buf + num, inp, rem); 68 inp += rem, len -= rem; 69 (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); 70 ctx->bufsz = 0; 71 /* ctx->buf is processed, ctx->num is guaranteed to be zero */ 72 } 73 74 if (len >= bsz) 75 rem = SHA3_absorb(ctx->A, inp, len, bsz); 76 else 77 rem = len; 78 79 if (rem) { 80 memcpy(ctx->buf, inp + len - rem, rem); 81 ctx->bufsz = rem; 82 } 83 84 return 1; 85} 86 87int ossl_sha3_final(unsigned char *md, KECCAK1600_CTX *ctx) 88{ 89 size_t bsz = ctx->block_size; 90 size_t num = ctx->bufsz; 91 92 if (ctx->md_size == 0) 93 return 1; 94 95 /* 96 * Pad the data with 10*1. Note that |num| can be |bsz - 1| 97 * in which case both byte operations below are performed on 98 * same byte... 99 */ 100 memset(ctx->buf + num, 0, bsz - num); 101 ctx->buf[num] = ctx->pad; 102 ctx->buf[bsz - 1] |= 0x80; 103 104 (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz); 105 106 SHA3_squeeze(ctx->A, md, ctx->md_size, bsz); 107 108 return 1; 109} 110