blob: 5df08f91c806e9418034c8f6131f8ae87cfccf9a [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
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020029static const uint64_t rc[24] = {
30 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
31 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
32 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
33 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
34 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
35 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
36};
37
38static const uint8_t rho[24] = {
39 1, 62, 28, 27, 36, 44, 6, 55, 20,
40 3, 10, 43, 25, 39, 41, 45, 15,
41 21, 8, 18, 2, 61, 56, 14
42};
43
44static const uint8_t pi[24] = {
45 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
46 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
47};
48
Pol Henarejosa6779282023-02-08 00:50:04 +010049#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
50#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
51} while (0)
52#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
53#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020054
55/* The permutation function. */
56static void keccak_f1600(mbedtls_sha3_context *ctx)
57{
58 uint64_t lane[5];
59 uint64_t *s = ctx->state;
60 int i;
61
Pol Henarejosa6779282023-02-08 00:50:04 +010062 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020063 uint64_t t;
64
65 /* Theta */
66 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
67 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
68 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
69 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
70 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
71
Pol Henarejosa6779282023-02-08 00:50:04 +010072 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020073 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
74
Pol Henarejosa6779282023-02-08 00:50:04 +010075 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020076 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
77
Pol Henarejosa6779282023-02-08 00:50:04 +010078 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020079 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
80
Pol Henarejosa6779282023-02-08 00:50:04 +010081 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020082 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
83
Pol Henarejosa6779282023-02-08 00:50:04 +010084 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020085 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
86
87 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +010088 for (i = 1; i < 25; i++) {
89 s[i] = ROT64(s[i], rho[i-1]);
90 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020091
92 /* Pi */
93 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +010094 for (i = 0; i < 24; i++) {
95 SWAP(s[pi[i]], t);
96 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020097
98 /* Chi */
99 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
100 s[0] ^= (~lane[1]) & lane[2];
101 s[1] ^= (~lane[2]) & lane[3];
102 s[2] ^= (~lane[3]) & lane[4];
103 s[3] ^= (~lane[4]) & lane[0];
104 s[4] ^= (~lane[0]) & lane[1];
105
106 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
107 s[5] ^= (~lane[1]) & lane[2];
108 s[6] ^= (~lane[2]) & lane[3];
109 s[7] ^= (~lane[3]) & lane[4];
110 s[8] ^= (~lane[4]) & lane[0];
111 s[9] ^= (~lane[0]) & lane[1];
112
113 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
114 s[10] ^= (~lane[1]) & lane[2];
115 s[11] ^= (~lane[2]) & lane[3];
116 s[12] ^= (~lane[3]) & lane[4];
117 s[13] ^= (~lane[4]) & lane[0];
118 s[14] ^= (~lane[0]) & lane[1];
119
120 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
121 s[15] ^= (~lane[1]) & lane[2];
122 s[16] ^= (~lane[2]) & lane[3];
123 s[17] ^= (~lane[3]) & lane[4];
124 s[18] ^= (~lane[4]) & lane[0];
125 s[19] ^= (~lane[0]) & lane[1];
126
127 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
128 s[20] ^= (~lane[1]) & lane[2];
129 s[21] ^= (~lane[2]) & lane[3];
130 s[22] ^= (~lane[3]) & lane[4];
131 s[23] ^= (~lane[4]) & lane[0];
132 s[24] ^= (~lane[0]) & lane[1];
133
134 /* Iota */
135 s[0] ^= rc[round];
136 }
137}
138
Pol Henarejosa6779282023-02-08 00:50:04 +0100139void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200140{
Pol Henarejosa6779282023-02-08 00:50:04 +0100141 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200142}
143
Pol Henarejosa6779282023-02-08 00:50:04 +0100144void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200145{
Pol Henarejosa6779282023-02-08 00:50:04 +0100146 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200147 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100148 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200149
Pol Henarejosa6779282023-02-08 00:50:04 +0100150 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200151}
152
Pol Henarejosa6779282023-02-08 00:50:04 +0100153void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
154 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200155{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200156 *dst = *src;
157}
158
159/*
160 * SHA-3 context setup
161 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100162int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200163{
Gilles Peskinea3172d12024-02-08 10:47:08 +0100164 switch (id) {
165 case MBEDTLS_SHA3_224:
166 ctx->olen = 224 / 8;
167 ctx->max_block_size = 1152 / 8;
Pol Henarejosa6779282023-02-08 00:50:04 +0100168 break;
Gilles Peskinea3172d12024-02-08 10:47:08 +0100169 case MBEDTLS_SHA3_256:
170 ctx->olen = 256 / 8;
171 ctx->max_block_size = 1088 / 8;
172 break;
173 case MBEDTLS_SHA3_384:
174 ctx->olen = 384 / 8;
175 ctx->max_block_size = 832 / 8;
176 break;
177 case MBEDTLS_SHA3_512:
178 ctx->olen = 512 / 8;
179 ctx->max_block_size = 576 / 8;
180 break;
181 default:
182 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejosa6779282023-02-08 00:50:04 +0100183 }
184
Pol Henarejosa6779282023-02-08 00:50:04 +0100185 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200186 ctx->index = 0;
187
Pol Henarejosa6779282023-02-08 00:50:04 +0100188 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200189}
190
191/*
192 * SHA-3 process buffer
193 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100194int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
195 const uint8_t *input,
196 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200197{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100198 if (ilen >= 8) {
199 // 8-byte align index
200 int align_bytes = 8 - (ctx->index % 8);
201 if (align_bytes) {
202 for (; align_bytes > 0; align_bytes--) {
203 ABSORB(ctx, ctx->index, *input++);
204 ilen--;
205 ctx->index++;
206 }
207 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
208 keccak_f1600(ctx);
209 }
210 }
211
212 // process input in 8-byte chunks
213 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100214 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100215 input += 8;
216 ilen -= 8;
217 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
218 keccak_f1600(ctx);
219 }
220 }
221 }
222
223 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100224 while (ilen-- > 0) {
225 ABSORB(ctx, ctx->index, *input++);
226 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
227 keccak_f1600(ctx);
228 }
229 }
230
231 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200232}
233
Pol Henarejosa6779282023-02-08 00:50:04 +0100234int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
235 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200236{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100237 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
238
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200239 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100240 if (ctx->olen > 0) {
241 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100242 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
243 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100244 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200245 olen = ctx->olen;
246 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200247
Dave Rodgman1789d842023-05-29 22:05:19 +0100248 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100249 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
250 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200251 ctx->index = 0;
252
Pol Henarejosa6779282023-02-08 00:50:04 +0100253 while (olen-- > 0) {
254 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200255
Pol Henarejosa6779282023-02-08 00:50:04 +0100256 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
257 keccak_f1600(ctx);
258 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200259 }
260
Dave Rodgmandbddb002023-08-30 18:43:23 +0100261 ret = 0;
262
263exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100264 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100265 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200266}
267
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200268/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100269 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200270 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100271int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
272 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200273{
274 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275 mbedtls_sha3_context ctx;
276
Pol Henarejosa6779282023-02-08 00:50:04 +0100277 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200278
Pol Henarejos85eeda02022-05-17 11:43:15 +0200279 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100280 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100282 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200283
Pol Henarejosa6779282023-02-08 00:50:04 +0100284 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200285 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100286 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200287
Pol Henarejosa6779282023-02-08 00:50:04 +0100288 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200289 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100290 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200291
292exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100293 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200294
Pol Henarejosa6779282023-02-08 00:50:04 +0100295 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200296}
297
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200298/**************** Self-tests ****************/
299
300#if defined(MBEDTLS_SELF_TEST)
301
302static const unsigned char test_data[2][4] =
303{
304 "",
305 "abc",
306};
307
308static const size_t test_data_len[2] =
309{
310 0, /* "" */
311 3 /* "abc" */
312};
313
314static const unsigned char test_hash_sha3_224[2][28] =
315{
316 { /* "" */
317 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
318 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
319 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
320 0x5B, 0x5A, 0x6B, 0xC7
321 },
322 { /* "abc" */
323 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
324 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
325 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
326 0x73, 0xB4, 0x6F, 0xDF
327 }
328};
329
330static const unsigned char test_hash_sha3_256[2][32] =
331{
332 { /* "" */
333 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
334 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
335 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
336 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
337 },
338 { /* "abc" */
339 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
340 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
341 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
342 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
343 }
344};
345
346static const unsigned char test_hash_sha3_384[2][48] =
347{
348 { /* "" */
349 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
350 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
351 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
352 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
353 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
354 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
355 },
356 { /* "abc" */
357 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
358 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
359 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
360 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
361 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
362 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
363 }
364};
365
366static const unsigned char test_hash_sha3_512[2][64] =
367{
368 { /* "" */
369 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
370 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
371 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
372 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
373 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
374 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
375 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
376 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
377 },
378 { /* "abc" */
379 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
380 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
381 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
382 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
383 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
384 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
385 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
386 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
387 }
388};
389
390static const unsigned char long_kat_hash_sha3_224[28] =
391{
392 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
393 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
394 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
395 0xA7, 0xFD, 0x65, 0x3C
396};
397
398static const unsigned char long_kat_hash_sha3_256[32] =
399{
400 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
401 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
402 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
403 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
404};
405
406static const unsigned char long_kat_hash_sha3_384[48] =
407{
408 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
409 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
410 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
411 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
412 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
413 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
414};
415
416static const unsigned char long_kat_hash_sha3_512[64] =
417{
418 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
419 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
420 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
421 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
422 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
423 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
424 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
425 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
426};
427
Pol Henarejosa6779282023-02-08 00:50:04 +0100428static int mbedtls_sha3_kat_test(int verbose,
429 const char *type_name,
430 mbedtls_sha3_id id,
431 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200432{
433 uint8_t hash[64];
434 int result;
435
Pol Henarejosa6779282023-02-08 00:50:04 +0100436 result = mbedtls_sha3(id,
437 test_data[test_num], test_data_len[test_num],
438 hash, sizeof(hash));
439 if (result != 0) {
440 if (verbose != 0) {
441 mbedtls_printf(" %s test %d error code: %d\n",
442 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200443 }
444
Pol Henarejosa6779282023-02-08 00:50:04 +0100445 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200446 }
447
Pol Henarejosa6779282023-02-08 00:50:04 +0100448 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200449 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100450 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200451 break;
452 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100453 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200454 break;
455 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100456 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200457 break;
458 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100459 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200460 break;
461 default:
462 break;
463 }
464
Pol Henarejosa6779282023-02-08 00:50:04 +0100465 if (0 != result) {
466 if (verbose != 0) {
467 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200468 }
469
Pol Henarejosa6779282023-02-08 00:50:04 +0100470 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200471 }
472
Pol Henarejosa6779282023-02-08 00:50:04 +0100473 if (verbose != 0) {
474 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200475 }
476
Pol Henarejosa6779282023-02-08 00:50:04 +0100477 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200478}
479
Pol Henarejosa6779282023-02-08 00:50:04 +0100480static int mbedtls_sha3_long_kat_test(int verbose,
481 const char *type_name,
482 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200483{
484 mbedtls_sha3_context ctx;
485 unsigned char buffer[1000];
486 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200487 int result = 0;
488
Pol Henarejosa6779282023-02-08 00:50:04 +0100489 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200490
Pol Henarejosa6779282023-02-08 00:50:04 +0100491 if (verbose != 0) {
492 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200493 }
494
Pol Henarejosa6779282023-02-08 00:50:04 +0100495 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200496
Pol Henarejosa6779282023-02-08 00:50:04 +0100497 result = mbedtls_sha3_starts(&ctx, id);
498 if (result != 0) {
499 if (verbose != 0) {
500 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200501 }
502 }
503
504 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100505 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100506 result = mbedtls_sha3_update(&ctx, buffer, 1000);
507 if (result != 0) {
508 if (verbose != 0) {
509 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200510 }
511
512 goto cleanup;
513 }
514 }
515
Pol Henarejosa6779282023-02-08 00:50:04 +0100516 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
517 if (result != 0) {
518 if (verbose != 0) {
519 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200520 }
521
522 goto cleanup;
523 }
524
Pol Henarejosa6779282023-02-08 00:50:04 +0100525 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200526 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100527 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200528 break;
529 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100530 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200531 break;
532 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100533 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200534 break;
535 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100536 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200537 break;
538 default:
539 break;
540 }
541
Pol Henarejosa6779282023-02-08 00:50:04 +0100542 if (result != 0) {
543 if (verbose != 0) {
544 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200545 }
546 }
547
Pol Henarejosa6779282023-02-08 00:50:04 +0100548 if (verbose != 0) {
549 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200550 }
551
552cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100553 mbedtls_sha3_free(&ctx);
554 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200555}
556
Pol Henarejosa6779282023-02-08 00:50:04 +0100557int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200558{
559 int i;
560
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100561 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100562 for (i = 0; i < 2; i++) {
563 if (0 != mbedtls_sha3_kat_test(verbose,
564 "SHA3-224", MBEDTLS_SHA3_224, i)) {
565 return 1;
566 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200567
Pol Henarejosa6779282023-02-08 00:50:04 +0100568 if (0 != mbedtls_sha3_kat_test(verbose,
569 "SHA3-256", MBEDTLS_SHA3_256, i)) {
570 return 1;
571 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200572
Pol Henarejosa6779282023-02-08 00:50:04 +0100573 if (0 != mbedtls_sha3_kat_test(verbose,
574 "SHA3-384", MBEDTLS_SHA3_384, i)) {
575 return 1;
576 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200577
Pol Henarejosa6779282023-02-08 00:50:04 +0100578 if (0 != mbedtls_sha3_kat_test(verbose,
579 "SHA3-512", MBEDTLS_SHA3_512, i)) {
580 return 1;
581 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200582 }
583
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100584 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100585 if (0 != mbedtls_sha3_long_kat_test(verbose,
586 "SHA3-224", MBEDTLS_SHA3_224)) {
587 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200588 }
589
Pol Henarejosa6779282023-02-08 00:50:04 +0100590 if (0 != mbedtls_sha3_long_kat_test(verbose,
591 "SHA3-256", MBEDTLS_SHA3_256)) {
592 return 1;
593 }
594
595 if (0 != mbedtls_sha3_long_kat_test(verbose,
596 "SHA3-384", MBEDTLS_SHA3_384)) {
597 return 1;
598 }
599
600 if (0 != mbedtls_sha3_long_kat_test(verbose,
601 "SHA3-512", MBEDTLS_SHA3_512)) {
602 return 1;
603 }
604
605 if (verbose != 0) {
606 mbedtls_printf("\n");
607 }
608
609 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200610}
611#endif /* MBEDTLS_SELF_TEST */
612
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200613#endif /* MBEDTLS_SHA3_C */