blob: d90fefaeac090652afb499a1bff8c4108678c14a [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
13#include "common.h"
14
15#if defined(MBEDTLS_SHA3_C)
16
17#include "mbedtls/sha3.h"
18#include "mbedtls/platform_util.h"
19#include "mbedtls/error.h"
20
21#include <string.h>
22
23#if defined(MBEDTLS_SELF_TEST)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020024#include "mbedtls/platform.h"
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020025#endif /* MBEDTLS_SELF_TEST */
26
Dave Rodgman1789d842023-05-29 22:05:19 +010027#define XOR_BYTE 0x6
28
Dave Rodgman9d7fa932023-05-29 22:07:06 +010029typedef struct mbedtls_sha3_family_functions {
30 mbedtls_sha3_id id;
31
32 uint16_t r;
33 uint16_t olen;
34}
35mbedtls_sha3_family_functions;
36
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020037/*
38 * List of supported SHA-3 families
39 */
40static mbedtls_sha3_family_functions sha3_families[] = {
Dave Rodgman1789d842023-05-29 22:05:19 +010041 { MBEDTLS_SHA3_224, 1152, 224 },
42 { MBEDTLS_SHA3_256, 1088, 256 },
43 { MBEDTLS_SHA3_384, 832, 384 },
44 { MBEDTLS_SHA3_512, 576, 512 },
45 { MBEDTLS_SHA3_NONE, 0, 0 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020046};
47
48static const uint64_t rc[24] = {
49 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
50 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
51 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
52 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
53 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
54 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
55};
56
57static const uint8_t rho[24] = {
58 1, 62, 28, 27, 36, 44, 6, 55, 20,
59 3, 10, 43, 25, 39, 41, 45, 15,
60 21, 8, 18, 2, 61, 56, 14
61};
62
63static const uint8_t pi[24] = {
64 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
65 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
66};
67
Pol Henarejosa6779282023-02-08 00:50:04 +010068#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
69#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
70} while (0)
71#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
72#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020073
74/* The permutation function. */
75static void keccak_f1600(mbedtls_sha3_context *ctx)
76{
77 uint64_t lane[5];
78 uint64_t *s = ctx->state;
79 int i;
80
Pol Henarejosa6779282023-02-08 00:50:04 +010081 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020082 uint64_t t;
83
84 /* Theta */
85 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
86 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
87 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
88 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
89 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
90
Pol Henarejosa6779282023-02-08 00:50:04 +010091 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020092 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
93
Pol Henarejosa6779282023-02-08 00:50:04 +010094 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020095 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
96
Pol Henarejosa6779282023-02-08 00:50:04 +010097 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020098 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
99
Pol Henarejosa6779282023-02-08 00:50:04 +0100100 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200101 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
102
Pol Henarejosa6779282023-02-08 00:50:04 +0100103 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200104 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
105
106 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +0100107 for (i = 1; i < 25; i++) {
108 s[i] = ROT64(s[i], rho[i-1]);
109 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200110
111 /* Pi */
112 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +0100113 for (i = 0; i < 24; i++) {
114 SWAP(s[pi[i]], t);
115 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200116
117 /* Chi */
118 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
119 s[0] ^= (~lane[1]) & lane[2];
120 s[1] ^= (~lane[2]) & lane[3];
121 s[2] ^= (~lane[3]) & lane[4];
122 s[3] ^= (~lane[4]) & lane[0];
123 s[4] ^= (~lane[0]) & lane[1];
124
125 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
126 s[5] ^= (~lane[1]) & lane[2];
127 s[6] ^= (~lane[2]) & lane[3];
128 s[7] ^= (~lane[3]) & lane[4];
129 s[8] ^= (~lane[4]) & lane[0];
130 s[9] ^= (~lane[0]) & lane[1];
131
132 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
133 s[10] ^= (~lane[1]) & lane[2];
134 s[11] ^= (~lane[2]) & lane[3];
135 s[12] ^= (~lane[3]) & lane[4];
136 s[13] ^= (~lane[4]) & lane[0];
137 s[14] ^= (~lane[0]) & lane[1];
138
139 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
140 s[15] ^= (~lane[1]) & lane[2];
141 s[16] ^= (~lane[2]) & lane[3];
142 s[17] ^= (~lane[3]) & lane[4];
143 s[18] ^= (~lane[4]) & lane[0];
144 s[19] ^= (~lane[0]) & lane[1];
145
146 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
147 s[20] ^= (~lane[1]) & lane[2];
148 s[21] ^= (~lane[2]) & lane[3];
149 s[22] ^= (~lane[3]) & lane[4];
150 s[23] ^= (~lane[4]) & lane[0];
151 s[24] ^= (~lane[0]) & lane[1];
152
153 /* Iota */
154 s[0] ^= rc[round];
155 }
156}
157
Pol Henarejosa6779282023-02-08 00:50:04 +0100158void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200159{
Pol Henarejosa6779282023-02-08 00:50:04 +0100160 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200161}
162
Pol Henarejosa6779282023-02-08 00:50:04 +0100163void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200164{
Pol Henarejosa6779282023-02-08 00:50:04 +0100165 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200166 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100167 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200168
Pol Henarejosa6779282023-02-08 00:50:04 +0100169 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200170}
171
Pol Henarejosa6779282023-02-08 00:50:04 +0100172void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
173 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200174{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200175 *dst = *src;
176}
177
178/*
179 * SHA-3 context setup
180 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100181int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200182{
183 mbedtls_sha3_family_functions *p = NULL;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200184
Pol Henarejosa6779282023-02-08 00:50:04 +0100185 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
186 if (p->id == id) {
187 break;
188 }
189 }
190
Tom Cosgrove876346e2023-09-09 14:24:46 +0100191 if (p->id == MBEDTLS_SHA3_NONE) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100192 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
193 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200194
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200195 ctx->olen = p->olen / 8;
Dave Rodgman1789d842023-05-29 22:05:19 +0100196 ctx->max_block_size = p->r / 8;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200197
Pol Henarejosa6779282023-02-08 00:50:04 +0100198 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200199 ctx->index = 0;
200
Pol Henarejosa6779282023-02-08 00:50:04 +0100201 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200202}
203
204/*
205 * SHA-3 process buffer
206 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100207int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
208 const uint8_t *input,
209 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200210{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100211 if (ilen >= 8) {
212 // 8-byte align index
213 int align_bytes = 8 - (ctx->index % 8);
214 if (align_bytes) {
215 for (; align_bytes > 0; align_bytes--) {
216 ABSORB(ctx, ctx->index, *input++);
217 ilen--;
218 ctx->index++;
219 }
220 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
221 keccak_f1600(ctx);
222 }
223 }
224
225 // process input in 8-byte chunks
226 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100227 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100228 input += 8;
229 ilen -= 8;
230 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
231 keccak_f1600(ctx);
232 }
233 }
234 }
235
236 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100237 while (ilen-- > 0) {
238 ABSORB(ctx, ctx->index, *input++);
239 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
240 keccak_f1600(ctx);
241 }
242 }
243
244 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200245}
246
Pol Henarejosa6779282023-02-08 00:50:04 +0100247int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
248 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200249{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100250 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
251
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200252 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100253 if (ctx->olen > 0) {
254 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100255 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
256 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100257 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200258 olen = ctx->olen;
259 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200260
Dave Rodgman1789d842023-05-29 22:05:19 +0100261 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100262 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
263 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200264 ctx->index = 0;
265
Pol Henarejosa6779282023-02-08 00:50:04 +0100266 while (olen-- > 0) {
267 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200268
Pol Henarejosa6779282023-02-08 00:50:04 +0100269 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
270 keccak_f1600(ctx);
271 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200272 }
273
Dave Rodgmandbddb002023-08-30 18:43:23 +0100274 ret = 0;
275
276exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100277 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100278 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200279}
280
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100282 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200283 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100284int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
285 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286{
287 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
288 mbedtls_sha3_context ctx;
289
Pol Henarejosa6779282023-02-08 00:50:04 +0100290 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200291
Pol Henarejos85eeda02022-05-17 11:43:15 +0200292 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100293 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200294 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100295 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200296
Pol Henarejosa6779282023-02-08 00:50:04 +0100297 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200298 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100299 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200300
Pol Henarejosa6779282023-02-08 00:50:04 +0100301 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200302 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100303 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200304
305exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100306 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200307
Pol Henarejosa6779282023-02-08 00:50:04 +0100308 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200309}
310
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200311/**************** Self-tests ****************/
312
313#if defined(MBEDTLS_SELF_TEST)
314
315static const unsigned char test_data[2][4] =
316{
317 "",
318 "abc",
319};
320
321static const size_t test_data_len[2] =
322{
323 0, /* "" */
324 3 /* "abc" */
325};
326
327static const unsigned char test_hash_sha3_224[2][28] =
328{
329 { /* "" */
330 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
331 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
332 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
333 0x5B, 0x5A, 0x6B, 0xC7
334 },
335 { /* "abc" */
336 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
337 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
338 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
339 0x73, 0xB4, 0x6F, 0xDF
340 }
341};
342
343static const unsigned char test_hash_sha3_256[2][32] =
344{
345 { /* "" */
346 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
347 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
348 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
349 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
350 },
351 { /* "abc" */
352 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
353 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
354 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
355 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
356 }
357};
358
359static const unsigned char test_hash_sha3_384[2][48] =
360{
361 { /* "" */
362 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
363 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
364 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
365 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
366 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
367 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
368 },
369 { /* "abc" */
370 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
371 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
372 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
373 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
374 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
375 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
376 }
377};
378
379static const unsigned char test_hash_sha3_512[2][64] =
380{
381 { /* "" */
382 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
383 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
384 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
385 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
386 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
387 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
388 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
389 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
390 },
391 { /* "abc" */
392 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
393 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
394 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
395 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
396 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
397 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
398 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
399 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
400 }
401};
402
403static const unsigned char long_kat_hash_sha3_224[28] =
404{
405 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
406 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
407 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
408 0xA7, 0xFD, 0x65, 0x3C
409};
410
411static const unsigned char long_kat_hash_sha3_256[32] =
412{
413 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
414 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
415 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
416 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
417};
418
419static const unsigned char long_kat_hash_sha3_384[48] =
420{
421 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
422 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
423 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
424 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
425 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
426 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
427};
428
429static const unsigned char long_kat_hash_sha3_512[64] =
430{
431 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
432 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
433 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
434 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
435 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
436 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
437 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
438 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
439};
440
Pol Henarejosa6779282023-02-08 00:50:04 +0100441static int mbedtls_sha3_kat_test(int verbose,
442 const char *type_name,
443 mbedtls_sha3_id id,
444 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200445{
446 uint8_t hash[64];
447 int result;
448
Pol Henarejosa6779282023-02-08 00:50:04 +0100449 result = mbedtls_sha3(id,
450 test_data[test_num], test_data_len[test_num],
451 hash, sizeof(hash));
452 if (result != 0) {
453 if (verbose != 0) {
454 mbedtls_printf(" %s test %d error code: %d\n",
455 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200456 }
457
Pol Henarejosa6779282023-02-08 00:50:04 +0100458 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200459 }
460
Pol Henarejosa6779282023-02-08 00:50:04 +0100461 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200462 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100463 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200464 break;
465 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100466 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200467 break;
468 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100469 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200470 break;
471 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100472 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200473 break;
474 default:
475 break;
476 }
477
Pol Henarejosa6779282023-02-08 00:50:04 +0100478 if (0 != result) {
479 if (verbose != 0) {
480 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200481 }
482
Pol Henarejosa6779282023-02-08 00:50:04 +0100483 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200484 }
485
Pol Henarejosa6779282023-02-08 00:50:04 +0100486 if (verbose != 0) {
487 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200488 }
489
Pol Henarejosa6779282023-02-08 00:50:04 +0100490 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200491}
492
Pol Henarejosa6779282023-02-08 00:50:04 +0100493static int mbedtls_sha3_long_kat_test(int verbose,
494 const char *type_name,
495 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200496{
497 mbedtls_sha3_context ctx;
498 unsigned char buffer[1000];
499 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200500 int result = 0;
501
Pol Henarejosa6779282023-02-08 00:50:04 +0100502 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503
Pol Henarejosa6779282023-02-08 00:50:04 +0100504 if (verbose != 0) {
505 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200506 }
507
Pol Henarejosa6779282023-02-08 00:50:04 +0100508 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200509
Pol Henarejosa6779282023-02-08 00:50:04 +0100510 result = mbedtls_sha3_starts(&ctx, id);
511 if (result != 0) {
512 if (verbose != 0) {
513 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200514 }
515 }
516
517 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100518 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100519 result = mbedtls_sha3_update(&ctx, buffer, 1000);
520 if (result != 0) {
521 if (verbose != 0) {
522 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200523 }
524
525 goto cleanup;
526 }
527 }
528
Pol Henarejosa6779282023-02-08 00:50:04 +0100529 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
530 if (result != 0) {
531 if (verbose != 0) {
532 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200533 }
534
535 goto cleanup;
536 }
537
Pol Henarejosa6779282023-02-08 00:50:04 +0100538 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200539 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100540 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200541 break;
542 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100543 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200544 break;
545 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100546 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200547 break;
548 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100549 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200550 break;
551 default:
552 break;
553 }
554
Pol Henarejosa6779282023-02-08 00:50:04 +0100555 if (result != 0) {
556 if (verbose != 0) {
557 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200558 }
559 }
560
Pol Henarejosa6779282023-02-08 00:50:04 +0100561 if (verbose != 0) {
562 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200563 }
564
565cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100566 mbedtls_sha3_free(&ctx);
567 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200568}
569
Pol Henarejosa6779282023-02-08 00:50:04 +0100570int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200571{
572 int i;
573
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100574 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100575 for (i = 0; i < 2; i++) {
576 if (0 != mbedtls_sha3_kat_test(verbose,
577 "SHA3-224", MBEDTLS_SHA3_224, i)) {
578 return 1;
579 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200580
Pol Henarejosa6779282023-02-08 00:50:04 +0100581 if (0 != mbedtls_sha3_kat_test(verbose,
582 "SHA3-256", MBEDTLS_SHA3_256, i)) {
583 return 1;
584 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200585
Pol Henarejosa6779282023-02-08 00:50:04 +0100586 if (0 != mbedtls_sha3_kat_test(verbose,
587 "SHA3-384", MBEDTLS_SHA3_384, i)) {
588 return 1;
589 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200590
Pol Henarejosa6779282023-02-08 00:50:04 +0100591 if (0 != mbedtls_sha3_kat_test(verbose,
592 "SHA3-512", MBEDTLS_SHA3_512, i)) {
593 return 1;
594 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200595 }
596
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100597 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100598 if (0 != mbedtls_sha3_long_kat_test(verbose,
599 "SHA3-224", MBEDTLS_SHA3_224)) {
600 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200601 }
602
Pol Henarejosa6779282023-02-08 00:50:04 +0100603 if (0 != mbedtls_sha3_long_kat_test(verbose,
604 "SHA3-256", MBEDTLS_SHA3_256)) {
605 return 1;
606 }
607
608 if (0 != mbedtls_sha3_long_kat_test(verbose,
609 "SHA3-384", MBEDTLS_SHA3_384)) {
610 return 1;
611 }
612
613 if (0 != mbedtls_sha3_long_kat_test(verbose,
614 "SHA3-512", MBEDTLS_SHA3_512)) {
615 return 1;
616 }
617
618 if (verbose != 0) {
619 mbedtls_printf("\n");
620 }
621
622 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200623}
624#endif /* MBEDTLS_SELF_TEST */
625
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200626#endif /* MBEDTLS_SHA3_C */