blob: 8b48cf75b2d2c4757a04ded3489cb1ae8b924559 [file] [log] [blame]
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +02001/*
2 * FIPS-202 compliant SHA3 implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19/*
20 * The SHA-3 Secure Hash Standard was published by NIST in 2015.
21 *
22 * https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
23 */
24
25#include "common.h"
26
27#if defined(MBEDTLS_SHA3_C)
28
29#include "mbedtls/sha3.h"
30#include "mbedtls/platform_util.h"
31#include "mbedtls/error.h"
32
33#include <string.h>
34
35#if defined(MBEDTLS_SELF_TEST)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020036#include "mbedtls/platform.h"
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020037#endif /* MBEDTLS_SELF_TEST */
38
Dave Rodgman1789d842023-05-29 22:05:19 +010039#define XOR_BYTE 0x6
40
Dave Rodgman9d7fa932023-05-29 22:07:06 +010041typedef struct mbedtls_sha3_family_functions {
42 mbedtls_sha3_id id;
43
44 uint16_t r;
45 uint16_t olen;
46}
47mbedtls_sha3_family_functions;
48
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020049/*
50 * List of supported SHA-3 families
51 */
52static mbedtls_sha3_family_functions sha3_families[] = {
Dave Rodgman1789d842023-05-29 22:05:19 +010053 { MBEDTLS_SHA3_224, 1152, 224 },
54 { MBEDTLS_SHA3_256, 1088, 256 },
55 { MBEDTLS_SHA3_384, 832, 384 },
56 { MBEDTLS_SHA3_512, 576, 512 },
57 { MBEDTLS_SHA3_NONE, 0, 0 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020058};
59
60static const uint64_t rc[24] = {
61 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
62 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
63 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
64 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
65 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
66 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
67};
68
69static const uint8_t rho[24] = {
70 1, 62, 28, 27, 36, 44, 6, 55, 20,
71 3, 10, 43, 25, 39, 41, 45, 15,
72 21, 8, 18, 2, 61, 56, 14
73};
74
75static const uint8_t pi[24] = {
76 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
77 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
78};
79
Pol Henarejosa6779282023-02-08 00:50:04 +010080#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
81#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
82} while (0)
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +010083#define ABSORB8(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << ((idx) << 3); \
84} while (0)
Pol Henarejosa6779282023-02-08 00:50:04 +010085#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
86#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020087
88/* The permutation function. */
89static void keccak_f1600(mbedtls_sha3_context *ctx)
90{
91 uint64_t lane[5];
92 uint64_t *s = ctx->state;
93 int i;
94
Pol Henarejosa6779282023-02-08 00:50:04 +010095 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020096 uint64_t t;
97
98 /* Theta */
99 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
100 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
101 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
102 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
103 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
104
Pol Henarejosa6779282023-02-08 00:50:04 +0100105 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200106 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
107
Pol Henarejosa6779282023-02-08 00:50:04 +0100108 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200109 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
110
Pol Henarejosa6779282023-02-08 00:50:04 +0100111 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200112 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
113
Pol Henarejosa6779282023-02-08 00:50:04 +0100114 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200115 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
116
Pol Henarejosa6779282023-02-08 00:50:04 +0100117 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200118 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
119
120 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +0100121 for (i = 1; i < 25; i++) {
122 s[i] = ROT64(s[i], rho[i-1]);
123 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200124
125 /* Pi */
126 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +0100127 for (i = 0; i < 24; i++) {
128 SWAP(s[pi[i]], t);
129 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200130
131 /* Chi */
132 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
133 s[0] ^= (~lane[1]) & lane[2];
134 s[1] ^= (~lane[2]) & lane[3];
135 s[2] ^= (~lane[3]) & lane[4];
136 s[3] ^= (~lane[4]) & lane[0];
137 s[4] ^= (~lane[0]) & lane[1];
138
139 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
140 s[5] ^= (~lane[1]) & lane[2];
141 s[6] ^= (~lane[2]) & lane[3];
142 s[7] ^= (~lane[3]) & lane[4];
143 s[8] ^= (~lane[4]) & lane[0];
144 s[9] ^= (~lane[0]) & lane[1];
145
146 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
147 s[10] ^= (~lane[1]) & lane[2];
148 s[11] ^= (~lane[2]) & lane[3];
149 s[12] ^= (~lane[3]) & lane[4];
150 s[13] ^= (~lane[4]) & lane[0];
151 s[14] ^= (~lane[0]) & lane[1];
152
153 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
154 s[15] ^= (~lane[1]) & lane[2];
155 s[16] ^= (~lane[2]) & lane[3];
156 s[17] ^= (~lane[3]) & lane[4];
157 s[18] ^= (~lane[4]) & lane[0];
158 s[19] ^= (~lane[0]) & lane[1];
159
160 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
161 s[20] ^= (~lane[1]) & lane[2];
162 s[21] ^= (~lane[2]) & lane[3];
163 s[22] ^= (~lane[3]) & lane[4];
164 s[23] ^= (~lane[4]) & lane[0];
165 s[24] ^= (~lane[0]) & lane[1];
166
167 /* Iota */
168 s[0] ^= rc[round];
169 }
170}
171
Pol Henarejosa6779282023-02-08 00:50:04 +0100172void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200173{
Pol Henarejosa6779282023-02-08 00:50:04 +0100174 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200175}
176
Pol Henarejosa6779282023-02-08 00:50:04 +0100177void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200178{
Pol Henarejosa6779282023-02-08 00:50:04 +0100179 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200180 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100181 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200182
Pol Henarejosa6779282023-02-08 00:50:04 +0100183 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200184}
185
Pol Henarejosa6779282023-02-08 00:50:04 +0100186void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
187 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200188{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200189 *dst = *src;
190}
191
192/*
193 * SHA-3 context setup
194 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100195int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200196{
197 mbedtls_sha3_family_functions *p = NULL;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200198
Pol Henarejosa6779282023-02-08 00:50:04 +0100199 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
200 if (p->id == id) {
201 break;
202 }
203 }
204
205 if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
206 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
207 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200208
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200209 ctx->olen = p->olen / 8;
Dave Rodgman1789d842023-05-29 22:05:19 +0100210 ctx->max_block_size = p->r / 8;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200211
Pol Henarejosa6779282023-02-08 00:50:04 +0100212 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200213 ctx->index = 0;
214
Pol Henarejosa6779282023-02-08 00:50:04 +0100215 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200216}
217
218/*
219 * SHA-3 process buffer
220 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100221int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
222 const uint8_t *input,
223 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200224{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100225 if (ilen >= 8) {
226 // 8-byte align index
227 int align_bytes = 8 - (ctx->index % 8);
228 if (align_bytes) {
229 for (; align_bytes > 0; align_bytes--) {
230 ABSORB(ctx, ctx->index, *input++);
231 ilen--;
232 ctx->index++;
233 }
234 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
235 keccak_f1600(ctx);
236 }
237 }
238
239 // process input in 8-byte chunks
240 while (ilen >= 8) {
241 ABSORB8(ctx, ctx->index, mbedtls_get_unaligned_uint64(input));
242 input += 8;
243 ilen -= 8;
244 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
245 keccak_f1600(ctx);
246 }
247 }
248 }
249
250 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100251 while (ilen-- > 0) {
252 ABSORB(ctx, ctx->index, *input++);
253 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
254 keccak_f1600(ctx);
255 }
256 }
257
258 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200259}
260
Pol Henarejosa6779282023-02-08 00:50:04 +0100261int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
262 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200263{
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200264 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100265 if (ctx->olen > 0) {
266 if (ctx->olen > olen) {
267 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
268 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200269 olen = ctx->olen;
270 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200271
Dave Rodgman1789d842023-05-29 22:05:19 +0100272 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100273 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
274 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200275 ctx->index = 0;
276
Pol Henarejosa6779282023-02-08 00:50:04 +0100277 while (olen-- > 0) {
278 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200279
Pol Henarejosa6779282023-02-08 00:50:04 +0100280 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
281 keccak_f1600(ctx);
282 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200283 }
284
Pol Henarejosa6779282023-02-08 00:50:04 +0100285 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286}
287
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200288/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100289 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200290 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100291int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
292 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200293{
294 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
295 mbedtls_sha3_context ctx;
296
Pol Henarejosa6779282023-02-08 00:50:04 +0100297 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200298
Pol Henarejos85eeda02022-05-17 11:43:15 +0200299 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100300 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200301 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100302 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200303
Pol Henarejosa6779282023-02-08 00:50:04 +0100304 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200305 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100306 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200307
Pol Henarejosa6779282023-02-08 00:50:04 +0100308 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200309 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100310 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200311
312exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100313 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200314
Pol Henarejosa6779282023-02-08 00:50:04 +0100315 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200316}
317
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200318/**************** Self-tests ****************/
319
320#if defined(MBEDTLS_SELF_TEST)
321
322static const unsigned char test_data[2][4] =
323{
324 "",
325 "abc",
326};
327
328static const size_t test_data_len[2] =
329{
330 0, /* "" */
331 3 /* "abc" */
332};
333
334static const unsigned char test_hash_sha3_224[2][28] =
335{
336 { /* "" */
337 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
338 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
339 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
340 0x5B, 0x5A, 0x6B, 0xC7
341 },
342 { /* "abc" */
343 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
344 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
345 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
346 0x73, 0xB4, 0x6F, 0xDF
347 }
348};
349
350static const unsigned char test_hash_sha3_256[2][32] =
351{
352 { /* "" */
353 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
354 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
355 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
356 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
357 },
358 { /* "abc" */
359 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
360 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
361 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
362 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
363 }
364};
365
366static const unsigned char test_hash_sha3_384[2][48] =
367{
368 { /* "" */
369 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
370 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
371 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
372 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
373 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
374 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
375 },
376 { /* "abc" */
377 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
378 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
379 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
380 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
381 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
382 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
383 }
384};
385
386static const unsigned char test_hash_sha3_512[2][64] =
387{
388 { /* "" */
389 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
390 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
391 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
392 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
393 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
394 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
395 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
396 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
397 },
398 { /* "abc" */
399 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
400 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
401 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
402 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
403 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
404 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
405 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
406 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
407 }
408};
409
410static const unsigned char long_kat_hash_sha3_224[28] =
411{
412 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
413 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
414 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
415 0xA7, 0xFD, 0x65, 0x3C
416};
417
418static const unsigned char long_kat_hash_sha3_256[32] =
419{
420 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
421 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
422 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
423 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
424};
425
426static const unsigned char long_kat_hash_sha3_384[48] =
427{
428 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
429 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
430 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
431 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
432 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
433 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
434};
435
436static const unsigned char long_kat_hash_sha3_512[64] =
437{
438 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
439 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
440 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
441 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
442 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
443 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
444 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
445 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
446};
447
Pol Henarejosa6779282023-02-08 00:50:04 +0100448static int mbedtls_sha3_kat_test(int verbose,
449 const char *type_name,
450 mbedtls_sha3_id id,
451 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200452{
453 uint8_t hash[64];
454 int result;
455
Pol Henarejosa6779282023-02-08 00:50:04 +0100456 result = mbedtls_sha3(id,
457 test_data[test_num], test_data_len[test_num],
458 hash, sizeof(hash));
459 if (result != 0) {
460 if (verbose != 0) {
461 mbedtls_printf(" %s test %d error code: %d\n",
462 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200463 }
464
Pol Henarejosa6779282023-02-08 00:50:04 +0100465 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200466 }
467
Pol Henarejosa6779282023-02-08 00:50:04 +0100468 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200469 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100470 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200471 break;
472 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100473 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200474 break;
475 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100476 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200477 break;
478 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100479 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200480 break;
481 default:
482 break;
483 }
484
Pol Henarejosa6779282023-02-08 00:50:04 +0100485 if (0 != result) {
486 if (verbose != 0) {
487 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200488 }
489
Pol Henarejosa6779282023-02-08 00:50:04 +0100490 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200491 }
492
Pol Henarejosa6779282023-02-08 00:50:04 +0100493 if (verbose != 0) {
494 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200495 }
496
Pol Henarejosa6779282023-02-08 00:50:04 +0100497 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200498}
499
Pol Henarejosa6779282023-02-08 00:50:04 +0100500static int mbedtls_sha3_long_kat_test(int verbose,
501 const char *type_name,
502 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503{
504 mbedtls_sha3_context ctx;
505 unsigned char buffer[1000];
506 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200507 int result = 0;
508
Pol Henarejosa6779282023-02-08 00:50:04 +0100509 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200510
Pol Henarejosa6779282023-02-08 00:50:04 +0100511 if (verbose != 0) {
512 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200513 }
514
Pol Henarejosa6779282023-02-08 00:50:04 +0100515 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200516
Pol Henarejosa6779282023-02-08 00:50:04 +0100517 result = mbedtls_sha3_starts(&ctx, id);
518 if (result != 0) {
519 if (verbose != 0) {
520 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200521 }
522 }
523
524 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100525 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100526 result = mbedtls_sha3_update(&ctx, buffer, 1000);
527 if (result != 0) {
528 if (verbose != 0) {
529 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200530 }
531
532 goto cleanup;
533 }
534 }
535
Pol Henarejosa6779282023-02-08 00:50:04 +0100536 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
537 if (result != 0) {
538 if (verbose != 0) {
539 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200540 }
541
542 goto cleanup;
543 }
544
Pol Henarejosa6779282023-02-08 00:50:04 +0100545 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200546 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100547 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200548 break;
549 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100550 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200551 break;
552 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100553 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200554 break;
555 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100556 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200557 break;
558 default:
559 break;
560 }
561
Pol Henarejosa6779282023-02-08 00:50:04 +0100562 if (result != 0) {
563 if (verbose != 0) {
564 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200565 }
566 }
567
Pol Henarejosa6779282023-02-08 00:50:04 +0100568 if (verbose != 0) {
569 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200570 }
571
572cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100573 mbedtls_sha3_free(&ctx);
574 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200575}
576
Pol Henarejosa6779282023-02-08 00:50:04 +0100577int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200578{
579 int i;
580
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100581 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100582 for (i = 0; i < 2; i++) {
583 if (0 != mbedtls_sha3_kat_test(verbose,
584 "SHA3-224", MBEDTLS_SHA3_224, i)) {
585 return 1;
586 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200587
Pol Henarejosa6779282023-02-08 00:50:04 +0100588 if (0 != mbedtls_sha3_kat_test(verbose,
589 "SHA3-256", MBEDTLS_SHA3_256, i)) {
590 return 1;
591 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200592
Pol Henarejosa6779282023-02-08 00:50:04 +0100593 if (0 != mbedtls_sha3_kat_test(verbose,
594 "SHA3-384", MBEDTLS_SHA3_384, i)) {
595 return 1;
596 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200597
Pol Henarejosa6779282023-02-08 00:50:04 +0100598 if (0 != mbedtls_sha3_kat_test(verbose,
599 "SHA3-512", MBEDTLS_SHA3_512, i)) {
600 return 1;
601 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200602 }
603
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100604 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100605 if (0 != mbedtls_sha3_long_kat_test(verbose,
606 "SHA3-224", MBEDTLS_SHA3_224)) {
607 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200608 }
609
Pol Henarejosa6779282023-02-08 00:50:04 +0100610 if (0 != mbedtls_sha3_long_kat_test(verbose,
611 "SHA3-256", MBEDTLS_SHA3_256)) {
612 return 1;
613 }
614
615 if (0 != mbedtls_sha3_long_kat_test(verbose,
616 "SHA3-384", MBEDTLS_SHA3_384)) {
617 return 1;
618 }
619
620 if (0 != mbedtls_sha3_long_kat_test(verbose,
621 "SHA3-512", MBEDTLS_SHA3_512)) {
622 return 1;
623 }
624
625 if (verbose != 0) {
626 mbedtls_printf("\n");
627 }
628
629 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200630}
631#endif /* MBEDTLS_SELF_TEST */
632
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200633#endif /* MBEDTLS_SHA3_C */