1*52c89f62Schristos /* $NetBSD: sha3.c,v 1.4 2024/01/19 19:32:42 christos Exp $ */
296999894Sriastradh
396999894Sriastradh /*-
496999894Sriastradh * Copyright (c) 2015 Taylor R. Campbell
596999894Sriastradh * All rights reserved.
696999894Sriastradh *
796999894Sriastradh * Redistribution and use in source and binary forms, with or without
896999894Sriastradh * modification, are permitted provided that the following conditions
996999894Sriastradh * are met:
1096999894Sriastradh * 1. Redistributions of source code must retain the above copyright
1196999894Sriastradh * notice, this list of conditions and the following disclaimer.
1296999894Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
1396999894Sriastradh * notice, this list of conditions and the following disclaimer in the
1496999894Sriastradh * documentation and/or other materials provided with the distribution.
1596999894Sriastradh *
1696999894Sriastradh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1796999894Sriastradh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1896999894Sriastradh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1996999894Sriastradh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2096999894Sriastradh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2196999894Sriastradh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2296999894Sriastradh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2396999894Sriastradh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2496999894Sriastradh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2596999894Sriastradh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2696999894Sriastradh * SUCH DAMAGE.
2796999894Sriastradh */
2896999894Sriastradh
2996999894Sriastradh /*
3031f72197Sandvar * SHA-3: FIPS-202, Permutation-Based Hash and Extendable-Output Functions
3196999894Sriastradh */
3296999894Sriastradh
3396999894Sriastradh #if HAVE_NBTOOL_CONFIG_H
3496999894Sriastradh #include "nbtool_config.h"
3596999894Sriastradh #endif
3696999894Sriastradh
3796999894Sriastradh #include <sys/cdefs.h>
3896999894Sriastradh
3996999894Sriastradh #if defined(_KERNEL) || defined(_STANDALONE)
4096999894Sriastradh
41*52c89f62Schristos __KERNEL_RCSID(0, "$NetBSD: sha3.c,v 1.4 2024/01/19 19:32:42 christos Exp $");
4296999894Sriastradh #include <lib/libkern/libkern.h>
4396999894Sriastradh
4496999894Sriastradh #define SHA3_ASSERT KASSERT
4596999894Sriastradh
4696999894Sriastradh #else
4796999894Sriastradh
48*52c89f62Schristos __RCSID("$NetBSD: sha3.c,v 1.4 2024/01/19 19:32:42 christos Exp $");
4996999894Sriastradh
5096999894Sriastradh #include "namespace.h"
5196999894Sriastradh
5296999894Sriastradh #include <assert.h>
5396999894Sriastradh #include <string.h>
5496999894Sriastradh
5596999894Sriastradh #define SHA3_ASSERT _DIAGASSERT
5696999894Sriastradh
5796999894Sriastradh #endif
5896999894Sriastradh
5996999894Sriastradh #include <sys/endian.h>
6096999894Sriastradh #include <sys/sha3.h>
6196999894Sriastradh
6296999894Sriastradh #include "keccak.h"
6396999894Sriastradh
6496999894Sriastradh /* XXX Disabled for now -- these will be libc-private. */
6596999894Sriastradh #if 0 && !defined(_KERNEL) && !defined(_STANDALONE)
6696999894Sriastradh #ifdef __weak_alias
6796999894Sriastradh __weak_alias(SHA3_224_Init,_SHA3_224_Init)
6896999894Sriastradh __weak_alias(SHA3_224_Update,_SHA3_224_Update)
6996999894Sriastradh __weak_alias(SHA3_224_Final,_SHA3_224_Final)
7096999894Sriastradh __weak_alias(SHA3_256_Init,_SHA3_256_Init)
7196999894Sriastradh __weak_alias(SHA3_256_Update,_SHA3_256_Update)
7296999894Sriastradh __weak_alias(SHA3_256_Final,_SHA3_256_Final)
7396999894Sriastradh __weak_alias(SHA3_384_Init,_SHA3_384_Init)
7496999894Sriastradh __weak_alias(SHA3_384_Update,_SHA3_384_Update)
7596999894Sriastradh __weak_alias(SHA3_384_Final,_SHA3_384_Final)
7696999894Sriastradh __weak_alias(SHA3_512_Init,_SHA3_512_Init)
7796999894Sriastradh __weak_alias(SHA3_512_Update,_SHA3_512_Update)
7896999894Sriastradh __weak_alias(SHA3_512_Final,_SHA3_512_Final)
7996999894Sriastradh __weak_alias(SHA3_Selftest,_SHA3_Selftest)
8096999894Sriastradh __weak_alias(SHAKE128_Init,_SHAKE128_Init)
8196999894Sriastradh __weak_alias(SHAKE128_Update,_SHAKE128_Update)
8296999894Sriastradh __weak_alias(SHAKE128_Final,_SHAKE128_Final)
8396999894Sriastradh __weak_alias(SHAKE256_Init,_SHAKE256_Init)
8496999894Sriastradh __weak_alias(SHAKE256_Update,_SHAKE256_Update)
8596999894Sriastradh __weak_alias(SHAKE256_Final,_SHAKE256_Final)
8696999894Sriastradh #endif /* __weak_alias */
8796999894Sriastradh #endif /* kernel/standalone */
8896999894Sriastradh
8996999894Sriastradh #define MIN(a,b) ((a) < (b) ? (a) : (b))
9000fb1a3aSriastradh #define arraycount(a) (sizeof(a)/sizeof((a)[0]))
9196999894Sriastradh
9296999894Sriastradh /*
9396999894Sriastradh * Common body. All the SHA-3 functions share code structure. They
9496999894Sriastradh * differ only in the size of the chunks they split the message into:
9596999894Sriastradh * for digest size d, they are split into chunks of 200 - d bytes.
9696999894Sriastradh */
9796999894Sriastradh
9896999894Sriastradh static inline unsigned
sha3_rate(unsigned d)9996999894Sriastradh sha3_rate(unsigned d)
10096999894Sriastradh {
10196999894Sriastradh const unsigned cw = 2*d/8; /* capacity in words */
10296999894Sriastradh
10396999894Sriastradh return 25 - cw;
10496999894Sriastradh }
10596999894Sriastradh
10696999894Sriastradh static void
sha3_init(struct sha3 * C,unsigned rw)10796999894Sriastradh sha3_init(struct sha3 *C, unsigned rw)
10896999894Sriastradh {
10996999894Sriastradh unsigned iw;
11096999894Sriastradh
11196999894Sriastradh C->nb = 8*rw;
11296999894Sriastradh for (iw = 0; iw < 25; iw++)
11396999894Sriastradh C->A[iw] = 0;
11496999894Sriastradh }
11596999894Sriastradh
11696999894Sriastradh static void
sha3_update(struct sha3 * C,const uint8_t * data,size_t len,unsigned rw)11796999894Sriastradh sha3_update(struct sha3 *C, const uint8_t *data, size_t len, unsigned rw)
11896999894Sriastradh {
11996999894Sriastradh uint64_t T;
12096999894Sriastradh unsigned ib, iw; /* index of byte/word */
12196999894Sriastradh
12296999894Sriastradh assert(0 < C->nb);
12396999894Sriastradh
12496999894Sriastradh /* If there's a partial word, try to fill it. */
12596999894Sriastradh if ((C->nb % 8) != 0) {
12696999894Sriastradh T = 0;
12796999894Sriastradh for (ib = 0; ib < MIN(len, C->nb % 8); ib++)
12896999894Sriastradh T |= (uint64_t)data[ib] << (8*ib);
12996999894Sriastradh C->A[rw - (C->nb + 7)/8] ^= T << (8*(8 - (C->nb % 8)));
13096999894Sriastradh C->nb -= ib;
13196999894Sriastradh data += ib;
13296999894Sriastradh len -= ib;
13396999894Sriastradh
13496999894Sriastradh /* If we filled the buffer, permute now. */
13596999894Sriastradh if (C->nb == 0) {
13696999894Sriastradh keccakf1600(C->A);
13796999894Sriastradh C->nb = 8*rw;
13896999894Sriastradh }
13996999894Sriastradh
14096999894Sriastradh /* If that exhausted the input, we're done. */
14196999894Sriastradh if (len == 0)
14296999894Sriastradh return;
14396999894Sriastradh }
14496999894Sriastradh
14596999894Sriastradh /* At a word boundary. Fill any partial buffer. */
14696999894Sriastradh assert((C->nb % 8) == 0);
14796999894Sriastradh if (C->nb < 8*rw) {
14896999894Sriastradh for (iw = 0; iw < MIN(len, C->nb)/8; iw++)
14996999894Sriastradh C->A[rw - C->nb/8 + iw] ^= le64dec(data + 8*iw);
15096999894Sriastradh C->nb -= 8*iw;
15196999894Sriastradh data += 8*iw;
15296999894Sriastradh len -= 8*iw;
15396999894Sriastradh
15496999894Sriastradh /* If we filled the buffer, permute now. */
15596999894Sriastradh if (C->nb == 0) {
15696999894Sriastradh keccakf1600(C->A);
15796999894Sriastradh C->nb = 8*rw;
15896999894Sriastradh } else {
15996999894Sriastradh /* Otherwise, less than a word left. */
16096999894Sriastradh assert(len < 8);
16196999894Sriastradh goto partial;
16296999894Sriastradh }
16396999894Sriastradh }
16496999894Sriastradh
16596999894Sriastradh /* At a buffer boundary. Absorb input one buffer at a time. */
16696999894Sriastradh assert(C->nb == 8*rw);
16796999894Sriastradh while (8*rw <= len) {
16896999894Sriastradh for (iw = 0; iw < rw; iw++)
16996999894Sriastradh C->A[iw] ^= le64dec(data + 8*iw);
17096999894Sriastradh keccakf1600(C->A);
17196999894Sriastradh data += 8*rw;
17296999894Sriastradh len -= 8*rw;
17396999894Sriastradh }
17496999894Sriastradh
17596999894Sriastradh /* Partially fill the buffer with as many words as we can. */
17696999894Sriastradh for (iw = 0; iw < len/8; iw++)
17796999894Sriastradh C->A[rw - C->nb/8 + iw] ^= le64dec(data + 8*iw);
17896999894Sriastradh C->nb -= 8*iw;
17996999894Sriastradh data += 8*iw;
18096999894Sriastradh len -= 8*iw;
18196999894Sriastradh
18296999894Sriastradh partial:
18396999894Sriastradh /* Partially fill the last word with as many bytes as we can. */
18496999894Sriastradh assert(len < 8);
18596999894Sriastradh assert(0 < C->nb);
18696999894Sriastradh assert((C->nb % 8) == 0);
18796999894Sriastradh T = 0;
18896999894Sriastradh for (ib = 0; ib < len; ib++)
18996999894Sriastradh T |= (uint64_t)data[ib] << (8*ib);
19096999894Sriastradh C->A[rw - C->nb/8] ^= T;
19196999894Sriastradh C->nb -= ib;
19296999894Sriastradh assert(0 < C->nb);
19396999894Sriastradh }
19496999894Sriastradh
19596999894Sriastradh static void
sha3_final(uint8_t * h,unsigned d,struct sha3 * C,unsigned rw)19696999894Sriastradh sha3_final(uint8_t *h, unsigned d, struct sha3 *C, unsigned rw)
19796999894Sriastradh {
19896999894Sriastradh unsigned nw, iw;
19996999894Sriastradh
20096999894Sriastradh assert(d <= 8*25);
20196999894Sriastradh assert(0 < C->nb);
20296999894Sriastradh
20396999894Sriastradh /* Append 01, pad with 10*1 up to buffer boundary, LSB first. */
20496999894Sriastradh nw = (C->nb + 7)/8;
20596999894Sriastradh assert(0 < nw);
20696999894Sriastradh assert(nw <= rw);
20796999894Sriastradh C->A[rw - nw] ^= (uint64_t)0x06 << (8*(8*nw - C->nb));
20896999894Sriastradh C->A[rw - 1] ^= 0x8000000000000000ULL;
20996999894Sriastradh
21096999894Sriastradh /* Permute one last time. */
21196999894Sriastradh keccakf1600(C->A);
21296999894Sriastradh
21396999894Sriastradh /* Reveal the first 8d bits of state, forget 1600-8d of them. */
21496999894Sriastradh for (iw = 0; iw < d/8; iw++)
21596999894Sriastradh le64enc(h + 8*iw, C->A[iw]);
21696999894Sriastradh h += 8*iw;
21796999894Sriastradh d -= 8*iw;
21896999894Sriastradh if (0 < d) {
21996999894Sriastradh /* For SHA3-224, we need to expose a partial word. */
22096999894Sriastradh uint64_t T = C->A[iw];
22196999894Sriastradh do {
22296999894Sriastradh *h++ = T & 0xff;
22396999894Sriastradh T >>= 8;
22496999894Sriastradh } while (--d);
22596999894Sriastradh }
22696999894Sriastradh (void)explicit_memset(C->A, 0, sizeof C->A);
22796999894Sriastradh C->nb = 0;
22896999894Sriastradh }
22996999894Sriastradh
23096999894Sriastradh static void
shake_final(uint8_t * h,size_t d,struct sha3 * C,unsigned rw)231*52c89f62Schristos shake_final(uint8_t *h, size_t d, struct sha3 *C, unsigned rw)
23296999894Sriastradh {
23396999894Sriastradh unsigned nw, iw;
23496999894Sriastradh
23596999894Sriastradh assert(0 < C->nb);
23696999894Sriastradh
23796999894Sriastradh /* Append 1111, pad with 10*1 up to buffer boundary, LSB first. */
23896999894Sriastradh nw = (C->nb + 7)/8;
23996999894Sriastradh assert(0 < nw);
24096999894Sriastradh assert(nw <= rw);
24196999894Sriastradh C->A[rw - nw] ^= (uint64_t)0x1f << (8*(8*nw - C->nb));
24296999894Sriastradh C->A[rw - 1] ^= 0x8000000000000000ULL;
24396999894Sriastradh
24496999894Sriastradh /* Permute, reveal first rw words of state, repeat. */
24596999894Sriastradh while (8*rw <= d) {
24696999894Sriastradh keccakf1600(C->A);
24796999894Sriastradh for (iw = 0; iw < rw; iw++)
24896999894Sriastradh le64enc(h + 8*iw, C->A[iw]);
24996999894Sriastradh h += 8*iw;
25096999894Sriastradh d -= 8*iw;
25196999894Sriastradh }
25296999894Sriastradh
25396999894Sriastradh /*
25496999894Sriastradh * If 8*rw (the output rate in bytes) does not divide d, more
25596999894Sriastradh * words are wanted: permute again and reveal a little more.
25696999894Sriastradh */
25796999894Sriastradh if (0 < d) {
25896999894Sriastradh keccakf1600(C->A);
25996999894Sriastradh for (iw = 0; iw < d/8; iw++)
26096999894Sriastradh le64enc(h + 8*iw, C->A[iw]);
26196999894Sriastradh h += 8*iw;
26296999894Sriastradh d -= 8*iw;
26396999894Sriastradh
26496999894Sriastradh /*
26596999894Sriastradh * If 8 does not divide d, more bytes are wanted:
26696999894Sriastradh * reveal them.
26796999894Sriastradh */
26896999894Sriastradh if (0 < d) {
26996999894Sriastradh uint64_t T = C->A[iw];
27096999894Sriastradh do {
27196999894Sriastradh *h++ = T & 0xff;
27296999894Sriastradh T >>= 8;
27396999894Sriastradh } while (--d);
27496999894Sriastradh }
27596999894Sriastradh }
27696999894Sriastradh
27796999894Sriastradh (void)explicit_memset(C->A, 0, sizeof C->A);
27896999894Sriastradh C->nb = 0;
27996999894Sriastradh }
28096999894Sriastradh
28196999894Sriastradh void
SHA3_224_Init(SHA3_224_CTX * C)28296999894Sriastradh SHA3_224_Init(SHA3_224_CTX *C)
28396999894Sriastradh {
28496999894Sriastradh
28596999894Sriastradh sha3_init(&C->C224, sha3_rate(SHA3_224_DIGEST_LENGTH));
28696999894Sriastradh }
28796999894Sriastradh
28896999894Sriastradh void
SHA3_224_Update(SHA3_224_CTX * C,const uint8_t * data,size_t len)28996999894Sriastradh SHA3_224_Update(SHA3_224_CTX *C, const uint8_t *data, size_t len)
29096999894Sriastradh {
29196999894Sriastradh
29296999894Sriastradh sha3_update(&C->C224, data, len, sha3_rate(SHA3_224_DIGEST_LENGTH));
29396999894Sriastradh }
29496999894Sriastradh
29596999894Sriastradh void
SHA3_224_Final(uint8_t h[SHA3_224_DIGEST_LENGTH],SHA3_224_CTX * C)29696999894Sriastradh SHA3_224_Final(uint8_t h[SHA3_224_DIGEST_LENGTH], SHA3_224_CTX *C)
29796999894Sriastradh {
29896999894Sriastradh
29996999894Sriastradh sha3_final(h, SHA3_224_DIGEST_LENGTH, &C->C224,
30096999894Sriastradh sha3_rate(SHA3_224_DIGEST_LENGTH));
30196999894Sriastradh }
30296999894Sriastradh
30396999894Sriastradh void
SHA3_256_Init(SHA3_256_CTX * C)30496999894Sriastradh SHA3_256_Init(SHA3_256_CTX *C)
30596999894Sriastradh {
30696999894Sriastradh
30796999894Sriastradh sha3_init(&C->C256, sha3_rate(SHA3_256_DIGEST_LENGTH));
30896999894Sriastradh }
30996999894Sriastradh
31096999894Sriastradh void
SHA3_256_Update(SHA3_256_CTX * C,const uint8_t * data,size_t len)31196999894Sriastradh SHA3_256_Update(SHA3_256_CTX *C, const uint8_t *data, size_t len)
31296999894Sriastradh {
31396999894Sriastradh
31496999894Sriastradh sha3_update(&C->C256, data, len, sha3_rate(SHA3_256_DIGEST_LENGTH));
31596999894Sriastradh }
31696999894Sriastradh
31796999894Sriastradh void
SHA3_256_Final(uint8_t h[SHA3_256_DIGEST_LENGTH],SHA3_256_CTX * C)31896999894Sriastradh SHA3_256_Final(uint8_t h[SHA3_256_DIGEST_LENGTH], SHA3_256_CTX *C)
31996999894Sriastradh {
32096999894Sriastradh
32196999894Sriastradh sha3_final(h, SHA3_256_DIGEST_LENGTH, &C->C256,
32296999894Sriastradh sha3_rate(SHA3_256_DIGEST_LENGTH));
32396999894Sriastradh }
32496999894Sriastradh
32596999894Sriastradh void
SHA3_384_Init(SHA3_384_CTX * C)32696999894Sriastradh SHA3_384_Init(SHA3_384_CTX *C)
32796999894Sriastradh {
32896999894Sriastradh
32996999894Sriastradh sha3_init(&C->C384, sha3_rate(SHA3_384_DIGEST_LENGTH));
33096999894Sriastradh }
33196999894Sriastradh
33296999894Sriastradh void
SHA3_384_Update(SHA3_384_CTX * C,const uint8_t * data,size_t len)33396999894Sriastradh SHA3_384_Update(SHA3_384_CTX *C, const uint8_t *data, size_t len)
33496999894Sriastradh {
33596999894Sriastradh
33696999894Sriastradh sha3_update(&C->C384, data, len, sha3_rate(SHA3_384_DIGEST_LENGTH));
33796999894Sriastradh }
33896999894Sriastradh
33996999894Sriastradh void
SHA3_384_Final(uint8_t h[SHA3_384_DIGEST_LENGTH],SHA3_384_CTX * C)34096999894Sriastradh SHA3_384_Final(uint8_t h[SHA3_384_DIGEST_LENGTH], SHA3_384_CTX *C)
34196999894Sriastradh {
34296999894Sriastradh
34396999894Sriastradh sha3_final(h, SHA3_384_DIGEST_LENGTH, &C->C384,
34496999894Sriastradh sha3_rate(SHA3_384_DIGEST_LENGTH));
34596999894Sriastradh }
34696999894Sriastradh
34796999894Sriastradh void
SHA3_512_Init(SHA3_512_CTX * C)34896999894Sriastradh SHA3_512_Init(SHA3_512_CTX *C)
34996999894Sriastradh {
35096999894Sriastradh
35196999894Sriastradh sha3_init(&C->C512, sha3_rate(SHA3_512_DIGEST_LENGTH));
35296999894Sriastradh }
35396999894Sriastradh
35496999894Sriastradh void
SHA3_512_Update(SHA3_512_CTX * C,const uint8_t * data,size_t len)35596999894Sriastradh SHA3_512_Update(SHA3_512_CTX *C, const uint8_t *data, size_t len)
35696999894Sriastradh {
35796999894Sriastradh
35896999894Sriastradh sha3_update(&C->C512, data, len, sha3_rate(SHA3_512_DIGEST_LENGTH));
35996999894Sriastradh }
36096999894Sriastradh
36196999894Sriastradh void
SHA3_512_Final(uint8_t h[SHA3_512_DIGEST_LENGTH],SHA3_512_CTX * C)36296999894Sriastradh SHA3_512_Final(uint8_t h[SHA3_512_DIGEST_LENGTH], SHA3_512_CTX *C)
36396999894Sriastradh {
36496999894Sriastradh
36596999894Sriastradh sha3_final(h, SHA3_512_DIGEST_LENGTH, &C->C512,
36696999894Sriastradh sha3_rate(SHA3_512_DIGEST_LENGTH));
36796999894Sriastradh }
36896999894Sriastradh
36996999894Sriastradh void
SHAKE128_Init(SHAKE128_CTX * C)37096999894Sriastradh SHAKE128_Init(SHAKE128_CTX *C)
37196999894Sriastradh {
37296999894Sriastradh
37396999894Sriastradh sha3_init(&C->C128, sha3_rate(128/8));
37496999894Sriastradh }
37596999894Sriastradh
37696999894Sriastradh void
SHAKE128_Update(SHAKE128_CTX * C,const uint8_t * data,size_t len)37796999894Sriastradh SHAKE128_Update(SHAKE128_CTX *C, const uint8_t *data, size_t len)
37896999894Sriastradh {
37996999894Sriastradh
38096999894Sriastradh sha3_update(&C->C128, data, len, sha3_rate(128/8));
38196999894Sriastradh }
38296999894Sriastradh
38396999894Sriastradh void
SHAKE128_Final(uint8_t * h,size_t d,SHAKE128_CTX * C)38496999894Sriastradh SHAKE128_Final(uint8_t *h, size_t d, SHAKE128_CTX *C)
38596999894Sriastradh {
38696999894Sriastradh
38796999894Sriastradh shake_final(h, d, &C->C128, sha3_rate(128/8));
38896999894Sriastradh }
38996999894Sriastradh
39096999894Sriastradh void
SHAKE256_Init(SHAKE256_CTX * C)39196999894Sriastradh SHAKE256_Init(SHAKE256_CTX *C)
39296999894Sriastradh {
39396999894Sriastradh
39496999894Sriastradh sha3_init(&C->C256, sha3_rate(256/8));
39596999894Sriastradh }
39696999894Sriastradh
39796999894Sriastradh void
SHAKE256_Update(SHAKE256_CTX * C,const uint8_t * data,size_t len)39896999894Sriastradh SHAKE256_Update(SHAKE256_CTX *C, const uint8_t *data, size_t len)
39996999894Sriastradh {
40096999894Sriastradh
40196999894Sriastradh sha3_update(&C->C256, data, len, sha3_rate(256/8));
40296999894Sriastradh }
40396999894Sriastradh
40496999894Sriastradh void
SHAKE256_Final(uint8_t * h,size_t d,SHAKE256_CTX * C)40596999894Sriastradh SHAKE256_Final(uint8_t *h, size_t d, SHAKE256_CTX *C)
40696999894Sriastradh {
40796999894Sriastradh
40896999894Sriastradh shake_final(h, d, &C->C256, sha3_rate(256/8));
40996999894Sriastradh }
41096999894Sriastradh
41196999894Sriastradh static void
sha3_selftest_prng(void * buf,size_t len,uint32_t seed)41296999894Sriastradh sha3_selftest_prng(void *buf, size_t len, uint32_t seed)
41396999894Sriastradh {
41496999894Sriastradh uint8_t *p = buf;
41596999894Sriastradh size_t n = len;
41696999894Sriastradh uint32_t t, a, b;
41796999894Sriastradh
41896999894Sriastradh a = 0xdead4bad * seed;
41996999894Sriastradh b = 1;
42096999894Sriastradh
42196999894Sriastradh while (n--) {
42296999894Sriastradh t = a + b;
42396999894Sriastradh *p++ = t >> 24;
42496999894Sriastradh a = b;
42596999894Sriastradh b = t;
42696999894Sriastradh }
42796999894Sriastradh }
42896999894Sriastradh
42996999894Sriastradh int
SHA3_Selftest(void)43096999894Sriastradh SHA3_Selftest(void)
43196999894Sriastradh {
43200fb1a3aSriastradh static const uint8_t d224_0[] = { /* SHA3-224(0-bit) */
43396999894Sriastradh 0x6b,0x4e,0x03,0x42,0x36,0x67,0xdb,0xb7,
43496999894Sriastradh 0x3b,0x6e,0x15,0x45,0x4f,0x0e,0xb1,0xab,
43596999894Sriastradh 0xd4,0x59,0x7f,0x9a,0x1b,0x07,0x8e,0x3f,
43696999894Sriastradh 0x5b,0x5a,0x6b,0xc7,
43796999894Sriastradh };
43800fb1a3aSriastradh static const uint8_t d256_0[] = { /* SHA3-256(0-bit) */
43996999894Sriastradh 0xa7,0xff,0xc6,0xf8,0xbf,0x1e,0xd7,0x66,
44096999894Sriastradh 0x51,0xc1,0x47,0x56,0xa0,0x61,0xd6,0x62,
44196999894Sriastradh 0xf5,0x80,0xff,0x4d,0xe4,0x3b,0x49,0xfa,
44296999894Sriastradh 0x82,0xd8,0x0a,0x4b,0x80,0xf8,0x43,0x4a,
44396999894Sriastradh };
44400fb1a3aSriastradh static const uint8_t d384_0[] = { /* SHA3-384(0-bit) */
44596999894Sriastradh 0x0c,0x63,0xa7,0x5b,0x84,0x5e,0x4f,0x7d,
44696999894Sriastradh 0x01,0x10,0x7d,0x85,0x2e,0x4c,0x24,0x85,
44796999894Sriastradh 0xc5,0x1a,0x50,0xaa,0xaa,0x94,0xfc,0x61,
44896999894Sriastradh 0x99,0x5e,0x71,0xbb,0xee,0x98,0x3a,0x2a,
44996999894Sriastradh 0xc3,0x71,0x38,0x31,0x26,0x4a,0xdb,0x47,
45096999894Sriastradh 0xfb,0x6b,0xd1,0xe0,0x58,0xd5,0xf0,0x04,
45196999894Sriastradh };
45200fb1a3aSriastradh static const uint8_t d512_0[] = { /* SHA3-512(0-bit) */
45396999894Sriastradh 0xa6,0x9f,0x73,0xcc,0xa2,0x3a,0x9a,0xc5,
45496999894Sriastradh 0xc8,0xb5,0x67,0xdc,0x18,0x5a,0x75,0x6e,
45596999894Sriastradh 0x97,0xc9,0x82,0x16,0x4f,0xe2,0x58,0x59,
45696999894Sriastradh 0xe0,0xd1,0xdc,0xc1,0x47,0x5c,0x80,0xa6,
45796999894Sriastradh 0x15,0xb2,0x12,0x3a,0xf1,0xf5,0xf9,0x4c,
45896999894Sriastradh 0x11,0xe3,0xe9,0x40,0x2c,0x3a,0xc5,0x58,
45996999894Sriastradh 0xf5,0x00,0x19,0x9d,0x95,0xb6,0xd3,0xe3,
46096999894Sriastradh 0x01,0x75,0x85,0x86,0x28,0x1d,0xcd,0x26,
46196999894Sriastradh };
46200fb1a3aSriastradh static const uint8_t shake128_0_41[] = { /* SHAKE128(0-bit, 41) */
46396999894Sriastradh 0x7f,0x9c,0x2b,0xa4,0xe8,0x8f,0x82,0x7d,
46496999894Sriastradh 0x61,0x60,0x45,0x50,0x76,0x05,0x85,0x3e,
46596999894Sriastradh 0xd7,0x3b,0x80,0x93,0xf6,0xef,0xbc,0x88,
46696999894Sriastradh 0xeb,0x1a,0x6e,0xac,0xfa,0x66,0xef,0x26,
46796999894Sriastradh 0x3c,0xb1,0xee,0xa9,0x88,0x00,0x4b,0x93,0x10,
46896999894Sriastradh };
46900fb1a3aSriastradh static const uint8_t shake256_0_73[] = { /* SHAKE256(0-bit, 73) */
47096999894Sriastradh 0x46,0xb9,0xdd,0x2b,0x0b,0xa8,0x8d,0x13,
47196999894Sriastradh 0x23,0x3b,0x3f,0xeb,0x74,0x3e,0xeb,0x24,
47296999894Sriastradh 0x3f,0xcd,0x52,0xea,0x62,0xb8,0x1b,0x82,
47396999894Sriastradh 0xb5,0x0c,0x27,0x64,0x6e,0xd5,0x76,0x2f,
47496999894Sriastradh 0xd7,0x5d,0xc4,0xdd,0xd8,0xc0,0xf2,0x00,
47596999894Sriastradh 0xcb,0x05,0x01,0x9d,0x67,0xb5,0x92,0xf6,
47696999894Sriastradh 0xfc,0x82,0x1c,0x49,0x47,0x9a,0xb4,0x86,
47796999894Sriastradh 0x40,0x29,0x2e,0xac,0xb3,0xb7,0xc4,0xbe,
47896999894Sriastradh 0x14,0x1e,0x96,0x61,0x6f,0xb1,0x39,0x57,0x69,
47996999894Sriastradh };
48000fb1a3aSriastradh static const uint8_t d224_1600[] = { /* SHA3-224(200 * 0xa3) */
48196999894Sriastradh 0x93,0x76,0x81,0x6a,0xba,0x50,0x3f,0x72,
48296999894Sriastradh 0xf9,0x6c,0xe7,0xeb,0x65,0xac,0x09,0x5d,
48396999894Sriastradh 0xee,0xe3,0xbe,0x4b,0xf9,0xbb,0xc2,0xa1,
48496999894Sriastradh 0xcb,0x7e,0x11,0xe0,
48596999894Sriastradh };
48600fb1a3aSriastradh static const uint8_t d256_1600[] = { /* SHA3-256(200 * 0xa3) */
48796999894Sriastradh 0x79,0xf3,0x8a,0xde,0xc5,0xc2,0x03,0x07,
48896999894Sriastradh 0xa9,0x8e,0xf7,0x6e,0x83,0x24,0xaf,0xbf,
48996999894Sriastradh 0xd4,0x6c,0xfd,0x81,0xb2,0x2e,0x39,0x73,
49096999894Sriastradh 0xc6,0x5f,0xa1,0xbd,0x9d,0xe3,0x17,0x87,
49196999894Sriastradh };
49200fb1a3aSriastradh static const uint8_t d384_1600[] = { /* SHA3-384(200 * 0xa3) */
49396999894Sriastradh 0x18,0x81,0xde,0x2c,0xa7,0xe4,0x1e,0xf9,
49496999894Sriastradh 0x5d,0xc4,0x73,0x2b,0x8f,0x5f,0x00,0x2b,
49596999894Sriastradh 0x18,0x9c,0xc1,0xe4,0x2b,0x74,0x16,0x8e,
49696999894Sriastradh 0xd1,0x73,0x26,0x49,0xce,0x1d,0xbc,0xdd,
49796999894Sriastradh 0x76,0x19,0x7a,0x31,0xfd,0x55,0xee,0x98,
49896999894Sriastradh 0x9f,0x2d,0x70,0x50,0xdd,0x47,0x3e,0x8f,
49996999894Sriastradh };
50000fb1a3aSriastradh static const uint8_t d512_1600[] = { /* SHA3-512(200 * 0xa3) */
50196999894Sriastradh 0xe7,0x6d,0xfa,0xd2,0x20,0x84,0xa8,0xb1,
50296999894Sriastradh 0x46,0x7f,0xcf,0x2f,0xfa,0x58,0x36,0x1b,
50396999894Sriastradh 0xec,0x76,0x28,0xed,0xf5,0xf3,0xfd,0xc0,
50496999894Sriastradh 0xe4,0x80,0x5d,0xc4,0x8c,0xae,0xec,0xa8,
50596999894Sriastradh 0x1b,0x7c,0x13,0xc3,0x0a,0xdf,0x52,0xa3,
50696999894Sriastradh 0x65,0x95,0x84,0x73,0x9a,0x2d,0xf4,0x6b,
50796999894Sriastradh 0xe5,0x89,0xc5,0x1c,0xa1,0xa4,0xa8,0x41,
50896999894Sriastradh 0x6d,0xf6,0x54,0x5a,0x1c,0xe8,0xba,0x00,
50996999894Sriastradh };
51000fb1a3aSriastradh static const uint8_t shake128_1600_41[] = {
51100fb1a3aSriastradh /* SHAKE128(200 * 0xa3, 41) */
51296999894Sriastradh 0x13,0x1a,0xb8,0xd2,0xb5,0x94,0x94,0x6b,
51396999894Sriastradh 0x9c,0x81,0x33,0x3f,0x9b,0xb6,0xe0,0xce,
51496999894Sriastradh 0x75,0xc3,0xb9,0x31,0x04,0xfa,0x34,0x69,
51596999894Sriastradh 0xd3,0x91,0x74,0x57,0x38,0x5d,0xa0,0x37,
51696999894Sriastradh 0xcf,0x23,0x2e,0xf7,0x16,0x4a,0x6d,0x1e,0xb4,
51796999894Sriastradh };
51800fb1a3aSriastradh static const uint8_t shake256_1600_73[] = {
51900fb1a3aSriastradh /* SHAKE256(200 * 0xa3, 73) */
52096999894Sriastradh 0xcd,0x8a,0x92,0x0e,0xd1,0x41,0xaa,0x04,
52196999894Sriastradh 0x07,0xa2,0x2d,0x59,0x28,0x86,0x52,0xe9,
52296999894Sriastradh 0xd9,0xf1,0xa7,0xee,0x0c,0x1e,0x7c,0x1c,
52396999894Sriastradh 0xa6,0x99,0x42,0x4d,0xa8,0x4a,0x90,0x4d,
52496999894Sriastradh 0x2d,0x70,0x0c,0xaa,0xe7,0x39,0x6e,0xce,
52596999894Sriastradh 0x96,0x60,0x44,0x40,0x57,0x7d,0xa4,0xf3,
52696999894Sriastradh 0xaa,0x22,0xae,0xb8,0x85,0x7f,0x96,0x1c,
52796999894Sriastradh 0x4c,0xd8,0xe0,0x6f,0x0a,0xe6,0x61,0x0b,
52896999894Sriastradh 0x10,0x48,0xa7,0xf6,0x4e,0x10,0x74,0xcd,0x62,
52996999894Sriastradh };
53000fb1a3aSriastradh static const uint8_t d0[] = {
53100fb1a3aSriastradh 0x5d,0x3e,0x45,0xdd,0x9b,0x6b,0xda,0xf8,
53200fb1a3aSriastradh 0xe6,0xe6,0xb8,0x72,0xfb,0xc5,0x0d,0x0a,
53300fb1a3aSriastradh 0x4f,0x52,0x65,0xb4,0x11,0xf1,0xa1,0x0c,
53400fb1a3aSriastradh 0x00,0xa4,0x74,0x6c,0x0f,0xc0,0xdc,0xe0,
53500fb1a3aSriastradh 0x97,0x73,0xd6,0x70,0xaf,0xd4,0x64,0x0b,
53600fb1a3aSriastradh 0x8c,0x52,0x32,0x4c,0x87,0x8c,0xfa,0x4a,
53700fb1a3aSriastradh 0xdc,0x11,0x66,0x91,0x66,0x5a,0x1e,0xa4,
53800fb1a3aSriastradh 0xd6,0x69,0x97,0xc7,0xcb,0xe2,0x73,0xca,
53996999894Sriastradh };
54000fb1a3aSriastradh static const unsigned mlen[] = { 0, 3, 128, 129, 255 };
54100fb1a3aSriastradh uint8_t m[255], d[73];
54200fb1a3aSriastradh struct sha3 sha3;
54300fb1a3aSriastradh SHA3_224_CTX *sha3224 = (SHA3_224_CTX *)&sha3;
54400fb1a3aSriastradh SHA3_256_CTX *sha3256 = (SHA3_256_CTX *)&sha3;
54500fb1a3aSriastradh SHA3_384_CTX *sha3384 = (SHA3_384_CTX *)&sha3;
54600fb1a3aSriastradh SHA3_512_CTX *sha3512 = (SHA3_512_CTX *)&sha3;
54700fb1a3aSriastradh SHAKE128_CTX *shake128 = (SHAKE128_CTX *)&sha3;
54800fb1a3aSriastradh SHAKE256_CTX *shake256 = (SHAKE256_CTX *)&sha3;
54996999894Sriastradh SHA3_512_CTX ctx;
55096999894Sriastradh unsigned mi;
55196999894Sriastradh
55296999894Sriastradh /*
55396999894Sriastradh * NIST test vectors from
55496999894Sriastradh * <http://csrc.nist.gov/groups/ST/toolkit/examples.html#aHashing>:
55596999894Sriastradh * 0-bit, 1600-bit repeated 0xa3 (= 0b10100011).
55696999894Sriastradh */
55700fb1a3aSriastradh SHA3_224_Init(sha3224);
55800fb1a3aSriastradh SHA3_224_Final(d, sha3224);
55996999894Sriastradh if (memcmp(d, d224_0, 28) != 0)
56096999894Sriastradh return -1;
56100fb1a3aSriastradh SHA3_256_Init(sha3256);
56200fb1a3aSriastradh SHA3_256_Final(d, sha3256);
56396999894Sriastradh if (memcmp(d, d256_0, 32) != 0)
56496999894Sriastradh return -1;
56500fb1a3aSriastradh SHA3_384_Init(sha3384);
56600fb1a3aSriastradh SHA3_384_Final(d, sha3384);
56796999894Sriastradh if (memcmp(d, d384_0, 48) != 0)
56896999894Sriastradh return -1;
56900fb1a3aSriastradh SHA3_512_Init(sha3512);
57000fb1a3aSriastradh SHA3_512_Final(d, sha3512);
57196999894Sriastradh if (memcmp(d, d512_0, 64) != 0)
57296999894Sriastradh return -1;
57300fb1a3aSriastradh SHAKE128_Init(shake128);
57400fb1a3aSriastradh SHAKE128_Final(d, 41, shake128);
57596999894Sriastradh if (memcmp(d, shake128_0_41, 41) != 0)
57696999894Sriastradh return -1;
57700fb1a3aSriastradh SHAKE256_Init(shake256);
57800fb1a3aSriastradh SHAKE256_Final(d, 73, shake256);
57996999894Sriastradh if (memcmp(d, shake256_0_73, 73) != 0)
58096999894Sriastradh return -1;
58196999894Sriastradh
58296999894Sriastradh (void)memset(m, 0xa3, 200);
58300fb1a3aSriastradh SHA3_224_Init(sha3224);
58400fb1a3aSriastradh SHA3_224_Update(sha3224, m, 200);
58500fb1a3aSriastradh SHA3_224_Final(d, sha3224);
58696999894Sriastradh if (memcmp(d, d224_1600, 28) != 0)
58796999894Sriastradh return -1;
58800fb1a3aSriastradh SHA3_256_Init(sha3256);
58900fb1a3aSriastradh SHA3_256_Update(sha3256, m, 200);
59000fb1a3aSriastradh SHA3_256_Final(d, sha3256);
59196999894Sriastradh if (memcmp(d, d256_1600, 32) != 0)
59296999894Sriastradh return -1;
59300fb1a3aSriastradh SHA3_384_Init(sha3384);
59400fb1a3aSriastradh SHA3_384_Update(sha3384, m, 200);
59500fb1a3aSriastradh SHA3_384_Final(d, sha3384);
59696999894Sriastradh if (memcmp(d, d384_1600, 48) != 0)
59796999894Sriastradh return -1;
59800fb1a3aSriastradh SHA3_512_Init(sha3512);
59900fb1a3aSriastradh SHA3_512_Update(sha3512, m, 200);
60000fb1a3aSriastradh SHA3_512_Final(d, sha3512);
60196999894Sriastradh if (memcmp(d, d512_1600, 64) != 0)
60296999894Sriastradh return -1;
60300fb1a3aSriastradh SHAKE128_Init(shake128);
60400fb1a3aSriastradh SHAKE128_Update(shake128, m, 200);
60500fb1a3aSriastradh SHAKE128_Final(d, 41, shake128);
60696999894Sriastradh if (memcmp(d, shake128_1600_41, 41) != 0)
60796999894Sriastradh return -1;
60800fb1a3aSriastradh SHAKE256_Init(shake256);
60900fb1a3aSriastradh SHAKE256_Update(shake256, m, 200);
61000fb1a3aSriastradh SHAKE256_Final(d, 73, shake256);
61196999894Sriastradh if (memcmp(d, shake256_1600_73, 73) != 0)
61296999894Sriastradh return -1;
61396999894Sriastradh
61496999894Sriastradh /*
61596999894Sriastradh * Hand-crufted test vectors with unaligned message lengths.
61696999894Sriastradh */
61796999894Sriastradh SHA3_512_Init(&ctx);
61800fb1a3aSriastradh for (mi = 0; mi < arraycount(mlen); mi++) {
61996999894Sriastradh sha3_selftest_prng(m, mlen[mi], (224/8)*mlen[mi]);
62000fb1a3aSriastradh SHA3_224_Init(sha3224);
62100fb1a3aSriastradh SHA3_224_Update(sha3224, m, mlen[mi]);
62200fb1a3aSriastradh SHA3_224_Final(d, sha3224);
62396999894Sriastradh SHA3_512_Update(&ctx, d, 224/8);
62496999894Sriastradh }
62500fb1a3aSriastradh for (mi = 0; mi < arraycount(mlen); mi++) {
62696999894Sriastradh sha3_selftest_prng(m, mlen[mi], (256/8)*mlen[mi]);
62700fb1a3aSriastradh SHA3_256_Init(sha3256);
62800fb1a3aSriastradh SHA3_256_Update(sha3256, m, mlen[mi]);
62900fb1a3aSriastradh SHA3_256_Final(d, sha3256);
63096999894Sriastradh SHA3_512_Update(&ctx, d, 256/8);
63196999894Sriastradh }
63200fb1a3aSriastradh for (mi = 0; mi < arraycount(mlen); mi++) {
63396999894Sriastradh sha3_selftest_prng(m, mlen[mi], (384/8)*mlen[mi]);
63400fb1a3aSriastradh SHA3_384_Init(sha3384);
63500fb1a3aSriastradh SHA3_384_Update(sha3384, m, mlen[mi]);
63600fb1a3aSriastradh SHA3_384_Final(d, sha3384);
63796999894Sriastradh SHA3_512_Update(&ctx, d, 384/8);
63896999894Sriastradh }
63900fb1a3aSriastradh for (mi = 0; mi < arraycount(mlen); mi++) {
64096999894Sriastradh sha3_selftest_prng(m, mlen[mi], (512/8)*mlen[mi]);
64100fb1a3aSriastradh SHA3_512_Init(sha3512);
64200fb1a3aSriastradh SHA3_512_Update(sha3512, m, mlen[mi]);
64300fb1a3aSriastradh SHA3_512_Final(d, sha3512);
64496999894Sriastradh SHA3_512_Update(&ctx, d, 512/8);
64596999894Sriastradh }
64696999894Sriastradh SHA3_512_Final(d, &ctx);
64796999894Sriastradh if (memcmp(d, d0, 64) != 0)
64896999894Sriastradh return -1;
64996999894Sriastradh
65096999894Sriastradh return 0;
65196999894Sriastradh }
652