blob: 99a8acbaaf1eebfdcab10f3fd6f33a9bf5cdb2cd [file] [log] [blame]
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +02001/*
2 * FIPS-202 compliant SHA3 implementation
3 *
4 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +02006 */
7/*
8 * The SHA-3 Secure Hash Standard was published by NIST in 2015.
9 *
10 * https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
11 */
12
Dave Rodgman6fd65422024-02-14 01:20:33 +000013#undef MBEDTLS_SHA3_THETA_UNROLL
14#define MBEDTLS_SHA3_RHO_UNROLL
15#define MBEDTLS_SHA3_PI_UNROLL
16
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020017#include "common.h"
18
19#if defined(MBEDTLS_SHA3_C)
20
21#include "mbedtls/sha3.h"
22#include "mbedtls/platform_util.h"
23#include "mbedtls/error.h"
24
25#include <string.h>
26
27#if defined(MBEDTLS_SELF_TEST)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020028#include "mbedtls/platform.h"
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020029#endif /* MBEDTLS_SELF_TEST */
30
Dave Rodgman1789d842023-05-29 22:05:19 +010031#define XOR_BYTE 0x6
32
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020033static const uint64_t rc[24] = {
34 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
35 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
36 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
37 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
38 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
39 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
40};
41
Dave Rodgmand407e0d2024-02-13 18:27:55 +000042static const uint32_t rho[6] = {
43 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020044};
45
Dave Rodgmancfb126f2024-02-13 18:35:41 +000046static const uint32_t pi[6] = {
47 0x0a070b11, 0x12030510, 0x08151804, 0x0f17130d, 0x0c02140e, 0x16090601
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020048};
49
Dave Rodgman255a0f52024-02-13 17:55:18 +000050#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
Pol Henarejosa6779282023-02-08 00:50:04 +010051#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
52} while (0)
53#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
54#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020055
56/* The permutation function. */
57static void keccak_f1600(mbedtls_sha3_context *ctx)
58{
59 uint64_t lane[5];
60 uint64_t *s = ctx->state;
61 int i;
62
Pol Henarejosa6779282023-02-08 00:50:04 +010063 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020064 uint64_t t;
65
66 /* Theta */
Dave Rodgman6fd65422024-02-14 01:20:33 +000067#if !defined(MBEDTLS_SHA3_THETA_UNROLL)
68 for (i = 0; i < 5; i++) {
69 lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
70 }
71 for (i = 0; i < 5; i++) {
72 t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
73 s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
74 }
75#else
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020076 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
77 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
78 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
79 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
80 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
81
Dave Rodgman255a0f52024-02-13 17:55:18 +000082 t = lane[4] ^ ROTR64(lane[1], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020083 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
84
Dave Rodgman255a0f52024-02-13 17:55:18 +000085 t = lane[0] ^ ROTR64(lane[2], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020086 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
87
Dave Rodgman255a0f52024-02-13 17:55:18 +000088 t = lane[1] ^ ROTR64(lane[3], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020089 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
90
Dave Rodgman255a0f52024-02-13 17:55:18 +000091 t = lane[2] ^ ROTR64(lane[4], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020092 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
93
Dave Rodgman255a0f52024-02-13 17:55:18 +000094 t = lane[3] ^ ROTR64(lane[0], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020095 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
Dave Rodgman6fd65422024-02-14 01:20:33 +000096#endif
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020097
98 /* Rho */
Dave Rodgmand407e0d2024-02-13 18:27:55 +000099 for (i = 1; i < 25; i += 4) {
100 uint32_t r = rho[(i - 1) >> 2];
Dave Rodgman6fd65422024-02-14 01:20:33 +0000101#if !defined(MBEDTLS_SHA3_RHO_UNROLL)
Dave Rodgmand407e0d2024-02-13 18:27:55 +0000102 for (int j = i; j < i + 4; j++) {
Dave Rodgman418f8592024-02-13 19:22:28 +0000103 uint8_t r8 = (uint8_t) (r >> 24);
Dave Rodgmand407e0d2024-02-13 18:27:55 +0000104 r <<= 8;
105 s[j] = ROTR64(s[j], r8);
106 }
Dave Rodgman6fd65422024-02-14 01:20:33 +0000107#else
108 s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
109 s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
110 s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
111 s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
112#endif
Pol Henarejosa6779282023-02-08 00:50:04 +0100113 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200114
115 /* Pi */
116 t = s[1];
Dave Rodgman6fd65422024-02-14 01:20:33 +0000117#if !defined(MBEDTLS_SHA3_PI_UNROLL)
Dave Rodgmancfb126f2024-02-13 18:35:41 +0000118 for (i = 0; i < 24; i += 4) {
119 uint32_t p = pi[i >> 2];
120 for (unsigned j = 0; j < 4; j++) {
121 uint8_t p8 = (uint8_t) (p >> 24);
122 p <<= 8;
123 SWAP(s[p8], t);
124 }
Pol Henarejosa6779282023-02-08 00:50:04 +0100125 }
Dave Rodgman6fd65422024-02-14 01:20:33 +0000126#else
127 uint32_t p = pi[0];
128 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
129 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
130 p = pi[1];
131 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
132 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
133 p = pi[2];
134 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
135 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
136 p = pi[3];
137 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
138 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
139 p = pi[4];
140 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
141 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
142 p = pi[5];
143 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
144 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
145#endif
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200146
147 /* Chi */
148 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
149 s[0] ^= (~lane[1]) & lane[2];
150 s[1] ^= (~lane[2]) & lane[3];
151 s[2] ^= (~lane[3]) & lane[4];
152 s[3] ^= (~lane[4]) & lane[0];
153 s[4] ^= (~lane[0]) & lane[1];
154
155 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
156 s[5] ^= (~lane[1]) & lane[2];
157 s[6] ^= (~lane[2]) & lane[3];
158 s[7] ^= (~lane[3]) & lane[4];
159 s[8] ^= (~lane[4]) & lane[0];
160 s[9] ^= (~lane[0]) & lane[1];
161
162 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
163 s[10] ^= (~lane[1]) & lane[2];
164 s[11] ^= (~lane[2]) & lane[3];
165 s[12] ^= (~lane[3]) & lane[4];
166 s[13] ^= (~lane[4]) & lane[0];
167 s[14] ^= (~lane[0]) & lane[1];
168
169 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
170 s[15] ^= (~lane[1]) & lane[2];
171 s[16] ^= (~lane[2]) & lane[3];
172 s[17] ^= (~lane[3]) & lane[4];
173 s[18] ^= (~lane[4]) & lane[0];
174 s[19] ^= (~lane[0]) & lane[1];
175
176 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
177 s[20] ^= (~lane[1]) & lane[2];
178 s[21] ^= (~lane[2]) & lane[3];
179 s[22] ^= (~lane[3]) & lane[4];
180 s[23] ^= (~lane[4]) & lane[0];
181 s[24] ^= (~lane[0]) & lane[1];
182
183 /* Iota */
184 s[0] ^= rc[round];
185 }
186}
187
Pol Henarejosa6779282023-02-08 00:50:04 +0100188void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200189{
Pol Henarejosa6779282023-02-08 00:50:04 +0100190 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200191}
192
Pol Henarejosa6779282023-02-08 00:50:04 +0100193void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200194{
Pol Henarejosa6779282023-02-08 00:50:04 +0100195 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200196 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100197 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200198
Pol Henarejosa6779282023-02-08 00:50:04 +0100199 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200200}
201
Pol Henarejosa6779282023-02-08 00:50:04 +0100202void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
203 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200204{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200205 *dst = *src;
206}
207
208/*
209 * SHA-3 context setup
210 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100211int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200212{
Gilles Peskinea3172d12024-02-08 10:47:08 +0100213 switch (id) {
214 case MBEDTLS_SHA3_224:
215 ctx->olen = 224 / 8;
216 ctx->max_block_size = 1152 / 8;
Pol Henarejosa6779282023-02-08 00:50:04 +0100217 break;
Gilles Peskinea3172d12024-02-08 10:47:08 +0100218 case MBEDTLS_SHA3_256:
219 ctx->olen = 256 / 8;
220 ctx->max_block_size = 1088 / 8;
221 break;
222 case MBEDTLS_SHA3_384:
223 ctx->olen = 384 / 8;
224 ctx->max_block_size = 832 / 8;
225 break;
226 case MBEDTLS_SHA3_512:
227 ctx->olen = 512 / 8;
228 ctx->max_block_size = 576 / 8;
229 break;
230 default:
231 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejosa6779282023-02-08 00:50:04 +0100232 }
233
Pol Henarejosa6779282023-02-08 00:50:04 +0100234 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200235 ctx->index = 0;
236
Pol Henarejosa6779282023-02-08 00:50:04 +0100237 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200238}
239
240/*
241 * SHA-3 process buffer
242 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100243int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
244 const uint8_t *input,
245 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200246{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100247 if (ilen >= 8) {
248 // 8-byte align index
249 int align_bytes = 8 - (ctx->index % 8);
250 if (align_bytes) {
251 for (; align_bytes > 0; align_bytes--) {
252 ABSORB(ctx, ctx->index, *input++);
253 ilen--;
254 ctx->index++;
255 }
256 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
257 keccak_f1600(ctx);
258 }
259 }
260
261 // process input in 8-byte chunks
262 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100263 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100264 input += 8;
265 ilen -= 8;
266 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
267 keccak_f1600(ctx);
268 }
269 }
270 }
271
272 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100273 while (ilen-- > 0) {
274 ABSORB(ctx, ctx->index, *input++);
275 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
276 keccak_f1600(ctx);
277 }
278 }
279
280 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281}
282
Pol Henarejosa6779282023-02-08 00:50:04 +0100283int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
284 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200285{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100286 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
287
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200288 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100289 if (ctx->olen > 0) {
290 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100291 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
292 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100293 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200294 olen = ctx->olen;
295 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200296
Dave Rodgman1789d842023-05-29 22:05:19 +0100297 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100298 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
299 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200300 ctx->index = 0;
301
Pol Henarejosa6779282023-02-08 00:50:04 +0100302 while (olen-- > 0) {
303 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200304
Pol Henarejosa6779282023-02-08 00:50:04 +0100305 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
306 keccak_f1600(ctx);
307 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200308 }
309
Dave Rodgmandbddb002023-08-30 18:43:23 +0100310 ret = 0;
311
312exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100313 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100314 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200315}
316
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200317/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100318 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200319 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100320int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
321 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200322{
323 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
324 mbedtls_sha3_context ctx;
325
Pol Henarejosa6779282023-02-08 00:50:04 +0100326 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200327
Pol Henarejos85eeda02022-05-17 11:43:15 +0200328 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100329 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200330 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100331 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200332
Pol Henarejosa6779282023-02-08 00:50:04 +0100333 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200334 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100335 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200336
Pol Henarejosa6779282023-02-08 00:50:04 +0100337 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200338 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100339 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200340
341exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100342 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200343
Pol Henarejosa6779282023-02-08 00:50:04 +0100344 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200345}
346
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200347/**************** Self-tests ****************/
348
349#if defined(MBEDTLS_SELF_TEST)
350
351static const unsigned char test_data[2][4] =
352{
353 "",
354 "abc",
355};
356
357static const size_t test_data_len[2] =
358{
359 0, /* "" */
360 3 /* "abc" */
361};
362
363static const unsigned char test_hash_sha3_224[2][28] =
364{
365 { /* "" */
366 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
367 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
368 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
369 0x5B, 0x5A, 0x6B, 0xC7
370 },
371 { /* "abc" */
372 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
373 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
374 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
375 0x73, 0xB4, 0x6F, 0xDF
376 }
377};
378
379static const unsigned char test_hash_sha3_256[2][32] =
380{
381 { /* "" */
382 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
383 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
384 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
385 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
386 },
387 { /* "abc" */
388 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
389 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
390 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
391 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
392 }
393};
394
395static const unsigned char test_hash_sha3_384[2][48] =
396{
397 { /* "" */
398 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
399 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
400 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
401 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
402 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
403 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
404 },
405 { /* "abc" */
406 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
407 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
408 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
409 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
410 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
411 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
412 }
413};
414
415static const unsigned char test_hash_sha3_512[2][64] =
416{
417 { /* "" */
418 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
419 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
420 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
421 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
422 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
423 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
424 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
425 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
426 },
427 { /* "abc" */
428 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
429 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
430 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
431 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
432 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
433 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
434 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
435 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
436 }
437};
438
439static const unsigned char long_kat_hash_sha3_224[28] =
440{
441 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
442 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
443 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
444 0xA7, 0xFD, 0x65, 0x3C
445};
446
447static const unsigned char long_kat_hash_sha3_256[32] =
448{
449 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
450 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
451 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
452 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
453};
454
455static const unsigned char long_kat_hash_sha3_384[48] =
456{
457 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
458 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
459 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
460 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
461 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
462 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
463};
464
465static const unsigned char long_kat_hash_sha3_512[64] =
466{
467 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
468 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
469 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
470 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
471 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
472 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
473 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
474 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
475};
476
Pol Henarejosa6779282023-02-08 00:50:04 +0100477static int mbedtls_sha3_kat_test(int verbose,
478 const char *type_name,
479 mbedtls_sha3_id id,
480 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200481{
482 uint8_t hash[64];
483 int result;
484
Pol Henarejosa6779282023-02-08 00:50:04 +0100485 result = mbedtls_sha3(id,
486 test_data[test_num], test_data_len[test_num],
487 hash, sizeof(hash));
488 if (result != 0) {
489 if (verbose != 0) {
490 mbedtls_printf(" %s test %d error code: %d\n",
491 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200492 }
493
Pol Henarejosa6779282023-02-08 00:50:04 +0100494 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200495 }
496
Pol Henarejosa6779282023-02-08 00:50:04 +0100497 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200498 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100499 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200500 break;
501 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100502 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503 break;
504 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100505 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200506 break;
507 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100508 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200509 break;
510 default:
511 break;
512 }
513
Pol Henarejosa6779282023-02-08 00:50:04 +0100514 if (0 != result) {
515 if (verbose != 0) {
516 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200517 }
518
Pol Henarejosa6779282023-02-08 00:50:04 +0100519 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200520 }
521
Pol Henarejosa6779282023-02-08 00:50:04 +0100522 if (verbose != 0) {
523 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200524 }
525
Pol Henarejosa6779282023-02-08 00:50:04 +0100526 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200527}
528
Pol Henarejosa6779282023-02-08 00:50:04 +0100529static int mbedtls_sha3_long_kat_test(int verbose,
530 const char *type_name,
531 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200532{
533 mbedtls_sha3_context ctx;
534 unsigned char buffer[1000];
535 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200536 int result = 0;
537
Pol Henarejosa6779282023-02-08 00:50:04 +0100538 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200539
Pol Henarejosa6779282023-02-08 00:50:04 +0100540 if (verbose != 0) {
541 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200542 }
543
Pol Henarejosa6779282023-02-08 00:50:04 +0100544 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200545
Pol Henarejosa6779282023-02-08 00:50:04 +0100546 result = mbedtls_sha3_starts(&ctx, id);
547 if (result != 0) {
548 if (verbose != 0) {
549 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200550 }
551 }
552
553 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100554 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100555 result = mbedtls_sha3_update(&ctx, buffer, 1000);
556 if (result != 0) {
557 if (verbose != 0) {
558 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200559 }
560
561 goto cleanup;
562 }
563 }
564
Pol Henarejosa6779282023-02-08 00:50:04 +0100565 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
566 if (result != 0) {
567 if (verbose != 0) {
568 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200569 }
570
571 goto cleanup;
572 }
573
Pol Henarejosa6779282023-02-08 00:50:04 +0100574 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200575 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100576 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200577 break;
578 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100579 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200580 break;
581 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100582 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200583 break;
584 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100585 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200586 break;
587 default:
588 break;
589 }
590
Pol Henarejosa6779282023-02-08 00:50:04 +0100591 if (result != 0) {
592 if (verbose != 0) {
593 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200594 }
595 }
596
Pol Henarejosa6779282023-02-08 00:50:04 +0100597 if (verbose != 0) {
598 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200599 }
600
601cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100602 mbedtls_sha3_free(&ctx);
603 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200604}
605
Pol Henarejosa6779282023-02-08 00:50:04 +0100606int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200607{
608 int i;
609
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100610 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100611 for (i = 0; i < 2; i++) {
612 if (0 != mbedtls_sha3_kat_test(verbose,
613 "SHA3-224", MBEDTLS_SHA3_224, i)) {
614 return 1;
615 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200616
Pol Henarejosa6779282023-02-08 00:50:04 +0100617 if (0 != mbedtls_sha3_kat_test(verbose,
618 "SHA3-256", MBEDTLS_SHA3_256, i)) {
619 return 1;
620 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200621
Pol Henarejosa6779282023-02-08 00:50:04 +0100622 if (0 != mbedtls_sha3_kat_test(verbose,
623 "SHA3-384", MBEDTLS_SHA3_384, i)) {
624 return 1;
625 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200626
Pol Henarejosa6779282023-02-08 00:50:04 +0100627 if (0 != mbedtls_sha3_kat_test(verbose,
628 "SHA3-512", MBEDTLS_SHA3_512, i)) {
629 return 1;
630 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200631 }
632
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100633 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100634 if (0 != mbedtls_sha3_long_kat_test(verbose,
635 "SHA3-224", MBEDTLS_SHA3_224)) {
636 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200637 }
638
Pol Henarejosa6779282023-02-08 00:50:04 +0100639 if (0 != mbedtls_sha3_long_kat_test(verbose,
640 "SHA3-256", MBEDTLS_SHA3_256)) {
641 return 1;
642 }
643
644 if (0 != mbedtls_sha3_long_kat_test(verbose,
645 "SHA3-384", MBEDTLS_SHA3_384)) {
646 return 1;
647 }
648
649 if (0 != mbedtls_sha3_long_kat_test(verbose,
650 "SHA3-512", MBEDTLS_SHA3_512)) {
651 return 1;
652 }
653
654 if (verbose != 0) {
655 mbedtls_printf("\n");
656 }
657
658 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200659}
660#endif /* MBEDTLS_SELF_TEST */
661
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200662#endif /* MBEDTLS_SHA3_C */