blob: 64a87a8a8275b6b4d456db25b5bec2bdb3da976b [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 Rodgmana111c0c2024-02-14 09:31:41 +000013/*
14 * These macros select manually unrolled implementations of parts of the main permutation function.
15 *
16 * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
17 * from manually unrolling at higher optimisation levels.
18 *
19 * Rolling up the theta loop saves a lot of code-size at small performance cost. The code-size
20 * saving then enables us to unroll the other loops for a net code-size saving with a net
21 * performance win.
22 */
23#undef MBEDTLS_SHA3_THETA_UNROLL //no-check-names
24#define MBEDTLS_SHA3_RHO_UNROLL //no-check-names
25#define MBEDTLS_SHA3_PI_UNROLL //no-check-names
26
Dave Rodgman6fd65422024-02-14 01:20:33 +000027
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020028#include "common.h"
29
30#if defined(MBEDTLS_SHA3_C)
31
32#include "mbedtls/sha3.h"
33#include "mbedtls/platform_util.h"
34#include "mbedtls/error.h"
35
36#include <string.h>
37
38#if defined(MBEDTLS_SELF_TEST)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020039#include "mbedtls/platform.h"
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020040#endif /* MBEDTLS_SELF_TEST */
41
Dave Rodgman1789d842023-05-29 22:05:19 +010042#define XOR_BYTE 0x6
43
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020044static const uint64_t rc[24] = {
45 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
46 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
47 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
48 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
49 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
50 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
51};
52
Dave Rodgmand407e0d2024-02-13 18:27:55 +000053static const uint32_t rho[6] = {
54 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020055};
56
Dave Rodgmancfb126f2024-02-13 18:35:41 +000057static const uint32_t pi[6] = {
58 0x0a070b11, 0x12030510, 0x08151804, 0x0f17130d, 0x0c02140e, 0x16090601
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020059};
60
Dave Rodgman255a0f52024-02-13 17:55:18 +000061#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
Pol Henarejosa6779282023-02-08 00:50:04 +010062#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
63} while (0)
64#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
65#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020066
67/* The permutation function. */
68static void keccak_f1600(mbedtls_sha3_context *ctx)
69{
70 uint64_t lane[5];
71 uint64_t *s = ctx->state;
72 int i;
73
Pol Henarejosa6779282023-02-08 00:50:04 +010074 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020075 uint64_t t;
76
77 /* Theta */
Dave Rodgman6fd65422024-02-14 01:20:33 +000078#if !defined(MBEDTLS_SHA3_THETA_UNROLL)
79 for (i = 0; i < 5; i++) {
80 lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
81 }
82 for (i = 0; i < 5; i++) {
83 t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
84 s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
85 }
86#else
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020087 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
88 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
89 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
90 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
91 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
92
Dave Rodgman255a0f52024-02-13 17:55:18 +000093 t = lane[4] ^ ROTR64(lane[1], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020094 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
95
Dave Rodgman255a0f52024-02-13 17:55:18 +000096 t = lane[0] ^ ROTR64(lane[2], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020097 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
98
Dave Rodgman255a0f52024-02-13 17:55:18 +000099 t = lane[1] ^ ROTR64(lane[3], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200100 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
101
Dave Rodgman255a0f52024-02-13 17:55:18 +0000102 t = lane[2] ^ ROTR64(lane[4], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200103 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
104
Dave Rodgman255a0f52024-02-13 17:55:18 +0000105 t = lane[3] ^ ROTR64(lane[0], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200106 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
Dave Rodgman6fd65422024-02-14 01:20:33 +0000107#endif
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200108
109 /* Rho */
Dave Rodgmand407e0d2024-02-13 18:27:55 +0000110 for (i = 1; i < 25; i += 4) {
111 uint32_t r = rho[(i - 1) >> 2];
Dave Rodgman6fd65422024-02-14 01:20:33 +0000112#if !defined(MBEDTLS_SHA3_RHO_UNROLL)
Dave Rodgmand407e0d2024-02-13 18:27:55 +0000113 for (int j = i; j < i + 4; j++) {
Dave Rodgman418f8592024-02-13 19:22:28 +0000114 uint8_t r8 = (uint8_t) (r >> 24);
Dave Rodgmand407e0d2024-02-13 18:27:55 +0000115 r <<= 8;
116 s[j] = ROTR64(s[j], r8);
117 }
Dave Rodgman6fd65422024-02-14 01:20:33 +0000118#else
119 s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
120 s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
121 s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
122 s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
123#endif
Pol Henarejosa6779282023-02-08 00:50:04 +0100124 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200125
126 /* Pi */
127 t = s[1];
Dave Rodgman6fd65422024-02-14 01:20:33 +0000128#if !defined(MBEDTLS_SHA3_PI_UNROLL)
Dave Rodgmancfb126f2024-02-13 18:35:41 +0000129 for (i = 0; i < 24; i += 4) {
130 uint32_t p = pi[i >> 2];
131 for (unsigned j = 0; j < 4; j++) {
132 uint8_t p8 = (uint8_t) (p >> 24);
133 p <<= 8;
134 SWAP(s[p8], t);
135 }
Pol Henarejosa6779282023-02-08 00:50:04 +0100136 }
Dave Rodgman6fd65422024-02-14 01:20:33 +0000137#else
138 uint32_t p = pi[0];
139 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
140 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
141 p = pi[1];
142 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
143 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
144 p = pi[2];
145 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
146 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
147 p = pi[3];
148 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
149 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
150 p = pi[4];
151 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
152 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
153 p = pi[5];
154 SWAP(s[MBEDTLS_BYTE_3(p)], t); SWAP(s[MBEDTLS_BYTE_2(p)], t);
155 SWAP(s[MBEDTLS_BYTE_1(p)], t); SWAP(s[MBEDTLS_BYTE_0(p)], t);
156#endif
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200157
158 /* Chi */
159 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
160 s[0] ^= (~lane[1]) & lane[2];
161 s[1] ^= (~lane[2]) & lane[3];
162 s[2] ^= (~lane[3]) & lane[4];
163 s[3] ^= (~lane[4]) & lane[0];
164 s[4] ^= (~lane[0]) & lane[1];
165
166 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
167 s[5] ^= (~lane[1]) & lane[2];
168 s[6] ^= (~lane[2]) & lane[3];
169 s[7] ^= (~lane[3]) & lane[4];
170 s[8] ^= (~lane[4]) & lane[0];
171 s[9] ^= (~lane[0]) & lane[1];
172
173 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
174 s[10] ^= (~lane[1]) & lane[2];
175 s[11] ^= (~lane[2]) & lane[3];
176 s[12] ^= (~lane[3]) & lane[4];
177 s[13] ^= (~lane[4]) & lane[0];
178 s[14] ^= (~lane[0]) & lane[1];
179
180 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
181 s[15] ^= (~lane[1]) & lane[2];
182 s[16] ^= (~lane[2]) & lane[3];
183 s[17] ^= (~lane[3]) & lane[4];
184 s[18] ^= (~lane[4]) & lane[0];
185 s[19] ^= (~lane[0]) & lane[1];
186
187 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
188 s[20] ^= (~lane[1]) & lane[2];
189 s[21] ^= (~lane[2]) & lane[3];
190 s[22] ^= (~lane[3]) & lane[4];
191 s[23] ^= (~lane[4]) & lane[0];
192 s[24] ^= (~lane[0]) & lane[1];
193
194 /* Iota */
195 s[0] ^= rc[round];
196 }
197}
198
Pol Henarejosa6779282023-02-08 00:50:04 +0100199void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200200{
Pol Henarejosa6779282023-02-08 00:50:04 +0100201 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200202}
203
Pol Henarejosa6779282023-02-08 00:50:04 +0100204void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200205{
Pol Henarejosa6779282023-02-08 00:50:04 +0100206 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200207 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100208 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200209
Pol Henarejosa6779282023-02-08 00:50:04 +0100210 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200211}
212
Pol Henarejosa6779282023-02-08 00:50:04 +0100213void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
214 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200215{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200216 *dst = *src;
217}
218
219/*
220 * SHA-3 context setup
221 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100222int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200223{
Gilles Peskinea3172d12024-02-08 10:47:08 +0100224 switch (id) {
225 case MBEDTLS_SHA3_224:
226 ctx->olen = 224 / 8;
227 ctx->max_block_size = 1152 / 8;
Pol Henarejosa6779282023-02-08 00:50:04 +0100228 break;
Gilles Peskinea3172d12024-02-08 10:47:08 +0100229 case MBEDTLS_SHA3_256:
230 ctx->olen = 256 / 8;
231 ctx->max_block_size = 1088 / 8;
232 break;
233 case MBEDTLS_SHA3_384:
234 ctx->olen = 384 / 8;
235 ctx->max_block_size = 832 / 8;
236 break;
237 case MBEDTLS_SHA3_512:
238 ctx->olen = 512 / 8;
239 ctx->max_block_size = 576 / 8;
240 break;
241 default:
242 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejosa6779282023-02-08 00:50:04 +0100243 }
244
Pol Henarejosa6779282023-02-08 00:50:04 +0100245 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200246 ctx->index = 0;
247
Pol Henarejosa6779282023-02-08 00:50:04 +0100248 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200249}
250
251/*
252 * SHA-3 process buffer
253 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100254int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
255 const uint8_t *input,
256 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200257{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100258 if (ilen >= 8) {
259 // 8-byte align index
260 int align_bytes = 8 - (ctx->index % 8);
261 if (align_bytes) {
262 for (; align_bytes > 0; align_bytes--) {
263 ABSORB(ctx, ctx->index, *input++);
264 ilen--;
265 ctx->index++;
266 }
267 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
268 keccak_f1600(ctx);
269 }
270 }
271
272 // process input in 8-byte chunks
273 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100274 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100275 input += 8;
276 ilen -= 8;
277 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
278 keccak_f1600(ctx);
279 }
280 }
281 }
282
283 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100284 while (ilen-- > 0) {
285 ABSORB(ctx, ctx->index, *input++);
286 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
287 keccak_f1600(ctx);
288 }
289 }
290
291 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200292}
293
Pol Henarejosa6779282023-02-08 00:50:04 +0100294int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
295 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200296{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100297 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
298
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200299 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100300 if (ctx->olen > 0) {
301 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100302 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
303 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100304 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200305 olen = ctx->olen;
306 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200307
Dave Rodgman1789d842023-05-29 22:05:19 +0100308 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100309 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
310 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200311 ctx->index = 0;
312
Pol Henarejosa6779282023-02-08 00:50:04 +0100313 while (olen-- > 0) {
314 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200315
Pol Henarejosa6779282023-02-08 00:50:04 +0100316 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
317 keccak_f1600(ctx);
318 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200319 }
320
Dave Rodgmandbddb002023-08-30 18:43:23 +0100321 ret = 0;
322
323exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100324 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100325 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200326}
327
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200328/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100329 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200330 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100331int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
332 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200333{
334 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
335 mbedtls_sha3_context ctx;
336
Pol Henarejosa6779282023-02-08 00:50:04 +0100337 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200338
Pol Henarejos85eeda02022-05-17 11:43:15 +0200339 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100340 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200341 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100342 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200343
Pol Henarejosa6779282023-02-08 00:50:04 +0100344 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200345 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100346 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200347
Pol Henarejosa6779282023-02-08 00:50:04 +0100348 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200349 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100350 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200351
352exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100353 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200354
Pol Henarejosa6779282023-02-08 00:50:04 +0100355 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200356}
357
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200358/**************** Self-tests ****************/
359
360#if defined(MBEDTLS_SELF_TEST)
361
362static const unsigned char test_data[2][4] =
363{
364 "",
365 "abc",
366};
367
368static const size_t test_data_len[2] =
369{
370 0, /* "" */
371 3 /* "abc" */
372};
373
374static const unsigned char test_hash_sha3_224[2][28] =
375{
376 { /* "" */
377 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
378 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
379 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
380 0x5B, 0x5A, 0x6B, 0xC7
381 },
382 { /* "abc" */
383 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
384 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
385 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
386 0x73, 0xB4, 0x6F, 0xDF
387 }
388};
389
390static const unsigned char test_hash_sha3_256[2][32] =
391{
392 { /* "" */
393 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
394 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
395 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
396 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
397 },
398 { /* "abc" */
399 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
400 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
401 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
402 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
403 }
404};
405
406static const unsigned char test_hash_sha3_384[2][48] =
407{
408 { /* "" */
409 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
410 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
411 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
412 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
413 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
414 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
415 },
416 { /* "abc" */
417 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
418 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
419 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
420 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
421 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
422 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
423 }
424};
425
426static const unsigned char test_hash_sha3_512[2][64] =
427{
428 { /* "" */
429 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
430 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
431 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
432 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
433 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
434 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
435 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
436 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
437 },
438 { /* "abc" */
439 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
440 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
441 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
442 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
443 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
444 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
445 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
446 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
447 }
448};
449
450static const unsigned char long_kat_hash_sha3_224[28] =
451{
452 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
453 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
454 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
455 0xA7, 0xFD, 0x65, 0x3C
456};
457
458static const unsigned char long_kat_hash_sha3_256[32] =
459{
460 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
461 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
462 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
463 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
464};
465
466static const unsigned char long_kat_hash_sha3_384[48] =
467{
468 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
469 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
470 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
471 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
472 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
473 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
474};
475
476static const unsigned char long_kat_hash_sha3_512[64] =
477{
478 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
479 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
480 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
481 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
482 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
483 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
484 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
485 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
486};
487
Pol Henarejosa6779282023-02-08 00:50:04 +0100488static int mbedtls_sha3_kat_test(int verbose,
489 const char *type_name,
490 mbedtls_sha3_id id,
491 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200492{
493 uint8_t hash[64];
494 int result;
495
Pol Henarejosa6779282023-02-08 00:50:04 +0100496 result = mbedtls_sha3(id,
497 test_data[test_num], test_data_len[test_num],
498 hash, sizeof(hash));
499 if (result != 0) {
500 if (verbose != 0) {
501 mbedtls_printf(" %s test %d error code: %d\n",
502 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503 }
504
Pol Henarejosa6779282023-02-08 00:50:04 +0100505 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200506 }
507
Pol Henarejosa6779282023-02-08 00:50:04 +0100508 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200509 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100510 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200511 break;
512 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100513 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200514 break;
515 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100516 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200517 break;
518 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100519 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200520 break;
521 default:
522 break;
523 }
524
Pol Henarejosa6779282023-02-08 00:50:04 +0100525 if (0 != result) {
526 if (verbose != 0) {
527 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200528 }
529
Pol Henarejosa6779282023-02-08 00:50:04 +0100530 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200531 }
532
Pol Henarejosa6779282023-02-08 00:50:04 +0100533 if (verbose != 0) {
534 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200535 }
536
Pol Henarejosa6779282023-02-08 00:50:04 +0100537 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200538}
539
Pol Henarejosa6779282023-02-08 00:50:04 +0100540static int mbedtls_sha3_long_kat_test(int verbose,
541 const char *type_name,
542 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200543{
544 mbedtls_sha3_context ctx;
545 unsigned char buffer[1000];
546 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200547 int result = 0;
548
Pol Henarejosa6779282023-02-08 00:50:04 +0100549 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200550
Pol Henarejosa6779282023-02-08 00:50:04 +0100551 if (verbose != 0) {
552 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200553 }
554
Pol Henarejosa6779282023-02-08 00:50:04 +0100555 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200556
Pol Henarejosa6779282023-02-08 00:50:04 +0100557 result = mbedtls_sha3_starts(&ctx, id);
558 if (result != 0) {
559 if (verbose != 0) {
560 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200561 }
562 }
563
564 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100565 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100566 result = mbedtls_sha3_update(&ctx, buffer, 1000);
567 if (result != 0) {
568 if (verbose != 0) {
569 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200570 }
571
572 goto cleanup;
573 }
574 }
575
Pol Henarejosa6779282023-02-08 00:50:04 +0100576 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
577 if (result != 0) {
578 if (verbose != 0) {
579 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200580 }
581
582 goto cleanup;
583 }
584
Pol Henarejosa6779282023-02-08 00:50:04 +0100585 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200586 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100587 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200588 break;
589 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100590 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200591 break;
592 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100593 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200594 break;
595 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100596 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200597 break;
598 default:
599 break;
600 }
601
Pol Henarejosa6779282023-02-08 00:50:04 +0100602 if (result != 0) {
603 if (verbose != 0) {
604 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200605 }
606 }
607
Pol Henarejosa6779282023-02-08 00:50:04 +0100608 if (verbose != 0) {
609 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200610 }
611
612cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100613 mbedtls_sha3_free(&ctx);
614 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200615}
616
Pol Henarejosa6779282023-02-08 00:50:04 +0100617int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200618{
619 int i;
620
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100621 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100622 for (i = 0; i < 2; i++) {
623 if (0 != mbedtls_sha3_kat_test(verbose,
624 "SHA3-224", MBEDTLS_SHA3_224, i)) {
625 return 1;
626 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200627
Pol Henarejosa6779282023-02-08 00:50:04 +0100628 if (0 != mbedtls_sha3_kat_test(verbose,
629 "SHA3-256", MBEDTLS_SHA3_256, i)) {
630 return 1;
631 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200632
Pol Henarejosa6779282023-02-08 00:50:04 +0100633 if (0 != mbedtls_sha3_kat_test(verbose,
634 "SHA3-384", MBEDTLS_SHA3_384, i)) {
635 return 1;
636 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200637
Pol Henarejosa6779282023-02-08 00:50:04 +0100638 if (0 != mbedtls_sha3_kat_test(verbose,
639 "SHA3-512", MBEDTLS_SHA3_512, i)) {
640 return 1;
641 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200642 }
643
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100644 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100645 if (0 != mbedtls_sha3_long_kat_test(verbose,
646 "SHA3-224", MBEDTLS_SHA3_224)) {
647 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200648 }
649
Pol Henarejosa6779282023-02-08 00:50:04 +0100650 if (0 != mbedtls_sha3_long_kat_test(verbose,
651 "SHA3-256", MBEDTLS_SHA3_256)) {
652 return 1;
653 }
654
655 if (0 != mbedtls_sha3_long_kat_test(verbose,
656 "SHA3-384", MBEDTLS_SHA3_384)) {
657 return 1;
658 }
659
660 if (0 != mbedtls_sha3_long_kat_test(verbose,
661 "SHA3-512", MBEDTLS_SHA3_512)) {
662 return 1;
663 }
664
665 if (verbose != 0) {
666 mbedtls_printf("\n");
667 }
668
669 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200670}
671#endif /* MBEDTLS_SELF_TEST */
672
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200673#endif /* MBEDTLS_SHA3_C */