blob: c5ce1c669f0d9474575c16e1a7f5b87dbe319cfd [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 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200175 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100176 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200177
Pol Henarejosa6779282023-02-08 00:50:04 +0100178 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200179}
180
Pol Henarejosa6779282023-02-08 00:50:04 +0100181void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200182{
Pol Henarejosa6779282023-02-08 00:50:04 +0100183 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200184 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100185 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200186
Pol Henarejosa6779282023-02-08 00:50:04 +0100187 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200188}
189
Pol Henarejosa6779282023-02-08 00:50:04 +0100190void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
191 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200192{
Pol Henarejosa6779282023-02-08 00:50:04 +0100193 if (dst == NULL || src == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200194 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100195 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200196
197 *dst = *src;
198}
199
200/*
201 * SHA-3 context setup
202 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100203int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200204{
205 mbedtls_sha3_family_functions *p = NULL;
Pol Henarejosa6779282023-02-08 00:50:04 +0100206 if (ctx == NULL) {
207 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200208 }
209
Pol Henarejosa6779282023-02-08 00:50:04 +0100210 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
211 if (p->id == id) {
212 break;
213 }
214 }
215
216 if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
217 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
218 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200219
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200220 ctx->olen = p->olen / 8;
Dave Rodgman1789d842023-05-29 22:05:19 +0100221 ctx->max_block_size = p->r / 8;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200222
Pol Henarejosa6779282023-02-08 00:50:04 +0100223 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200224 ctx->index = 0;
225
Pol Henarejosa6779282023-02-08 00:50:04 +0100226 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200227}
228
229/*
230 * SHA-3 process buffer
231 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100232int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
233 const uint8_t *input,
234 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200235{
Pol Henarejosa6779282023-02-08 00:50:04 +0100236 if (ctx == NULL) {
237 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200238 }
239
Pol Henarejosa6779282023-02-08 00:50:04 +0100240 if (ilen == 0 || input == NULL) {
241 return 0;
242 }
243
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100244 if (ilen >= 8) {
245 // 8-byte align index
246 int align_bytes = 8 - (ctx->index % 8);
247 if (align_bytes) {
248 for (; align_bytes > 0; align_bytes--) {
249 ABSORB(ctx, ctx->index, *input++);
250 ilen--;
251 ctx->index++;
252 }
253 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
254 keccak_f1600(ctx);
255 }
256 }
257
258 // process input in 8-byte chunks
259 while (ilen >= 8) {
260 ABSORB8(ctx, ctx->index, mbedtls_get_unaligned_uint64(input));
261 input += 8;
262 ilen -= 8;
263 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
264 keccak_f1600(ctx);
265 }
266 }
267 }
268
269 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100270 while (ilen-- > 0) {
271 ABSORB(ctx, ctx->index, *input++);
272 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
273 keccak_f1600(ctx);
274 }
275 }
276
277 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200278}
279
Pol Henarejosa6779282023-02-08 00:50:04 +0100280int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
281 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200282{
Pol Henarejosa6779282023-02-08 00:50:04 +0100283 if (ctx == NULL || output == NULL) {
284 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
285 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200287 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100288 if (ctx->olen > 0) {
289 if (ctx->olen > olen) {
290 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
291 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200292 olen = ctx->olen;
293 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200294
Dave Rodgman1789d842023-05-29 22:05:19 +0100295 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100296 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
297 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200298 ctx->index = 0;
299
Pol Henarejosa6779282023-02-08 00:50:04 +0100300 while (olen-- > 0) {
301 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200302
Pol Henarejosa6779282023-02-08 00:50:04 +0100303 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
304 keccak_f1600(ctx);
305 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200306 }
307
Pol Henarejosa6779282023-02-08 00:50:04 +0100308 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200309}
310
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200311/*
312 * output = SHA3( input buffer )
313 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100314int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
315 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200316{
317 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
318 mbedtls_sha3_context ctx;
319
Pol Henarejosa6779282023-02-08 00:50:04 +0100320 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200321
Pol Henarejos85eeda02022-05-17 11:43:15 +0200322 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100323 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200324 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100325 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200326
Pol Henarejosa6779282023-02-08 00:50:04 +0100327 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200328 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100329 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200330
Pol Henarejosa6779282023-02-08 00:50:04 +0100331 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200332 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100333 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200334
335exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100336 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200337
Pol Henarejosa6779282023-02-08 00:50:04 +0100338 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200339}
340
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200341/**************** Self-tests ****************/
342
343#if defined(MBEDTLS_SELF_TEST)
344
345static const unsigned char test_data[2][4] =
346{
347 "",
348 "abc",
349};
350
351static const size_t test_data_len[2] =
352{
353 0, /* "" */
354 3 /* "abc" */
355};
356
357static const unsigned char test_hash_sha3_224[2][28] =
358{
359 { /* "" */
360 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
361 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
362 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
363 0x5B, 0x5A, 0x6B, 0xC7
364 },
365 { /* "abc" */
366 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
367 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
368 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
369 0x73, 0xB4, 0x6F, 0xDF
370 }
371};
372
373static const unsigned char test_hash_sha3_256[2][32] =
374{
375 { /* "" */
376 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
377 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
378 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
379 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
380 },
381 { /* "abc" */
382 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
383 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
384 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
385 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
386 }
387};
388
389static const unsigned char test_hash_sha3_384[2][48] =
390{
391 { /* "" */
392 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
393 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
394 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
395 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
396 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
397 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
398 },
399 { /* "abc" */
400 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
401 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
402 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
403 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
404 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
405 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
406 }
407};
408
409static const unsigned char test_hash_sha3_512[2][64] =
410{
411 { /* "" */
412 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
413 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
414 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
415 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
416 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
417 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
418 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
419 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
420 },
421 { /* "abc" */
422 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
423 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
424 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
425 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
426 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
427 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
428 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
429 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
430 }
431};
432
433static const unsigned char long_kat_hash_sha3_224[28] =
434{
435 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
436 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
437 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
438 0xA7, 0xFD, 0x65, 0x3C
439};
440
441static const unsigned char long_kat_hash_sha3_256[32] =
442{
443 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
444 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
445 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
446 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
447};
448
449static const unsigned char long_kat_hash_sha3_384[48] =
450{
451 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
452 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
453 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
454 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
455 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
456 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
457};
458
459static const unsigned char long_kat_hash_sha3_512[64] =
460{
461 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
462 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
463 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
464 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
465 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
466 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
467 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
468 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
469};
470
Pol Henarejosa6779282023-02-08 00:50:04 +0100471static int mbedtls_sha3_kat_test(int verbose,
472 const char *type_name,
473 mbedtls_sha3_id id,
474 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200475{
476 uint8_t hash[64];
477 int result;
478
Pol Henarejosa6779282023-02-08 00:50:04 +0100479 result = mbedtls_sha3(id,
480 test_data[test_num], test_data_len[test_num],
481 hash, sizeof(hash));
482 if (result != 0) {
483 if (verbose != 0) {
484 mbedtls_printf(" %s test %d error code: %d\n",
485 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200486 }
487
Pol Henarejosa6779282023-02-08 00:50:04 +0100488 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200489 }
490
Pol Henarejosa6779282023-02-08 00:50:04 +0100491 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200492 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100493 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200494 break;
495 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100496 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200497 break;
498 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100499 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200500 break;
501 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100502 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503 break;
504 default:
505 break;
506 }
507
Pol Henarejosa6779282023-02-08 00:50:04 +0100508 if (0 != result) {
509 if (verbose != 0) {
510 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200511 }
512
Pol Henarejosa6779282023-02-08 00:50:04 +0100513 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200514 }
515
Pol Henarejosa6779282023-02-08 00:50:04 +0100516 if (verbose != 0) {
517 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200518 }
519
Pol Henarejosa6779282023-02-08 00:50:04 +0100520 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200521}
522
Pol Henarejosa6779282023-02-08 00:50:04 +0100523static int mbedtls_sha3_long_kat_test(int verbose,
524 const char *type_name,
525 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200526{
527 mbedtls_sha3_context ctx;
528 unsigned char buffer[1000];
529 unsigned char hash[64];
530 int i;
531 int result = 0;
532
Pol Henarejosa6779282023-02-08 00:50:04 +0100533 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200534
Pol Henarejosa6779282023-02-08 00:50:04 +0100535 if (verbose != 0) {
536 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200537 }
538
Pol Henarejosa6779282023-02-08 00:50:04 +0100539 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200540
Pol Henarejosa6779282023-02-08 00:50:04 +0100541 result = mbedtls_sha3_starts(&ctx, id);
542 if (result != 0) {
543 if (verbose != 0) {
544 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200545 }
546 }
547
548 /* Process 1,000,000 (one million) 'a' characters */
Pol Henarejosa6779282023-02-08 00:50:04 +0100549 for (i = 0; i < 1000; i++) {
550 result = mbedtls_sha3_update(&ctx, buffer, 1000);
551 if (result != 0) {
552 if (verbose != 0) {
553 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200554 }
555
556 goto cleanup;
557 }
558 }
559
Pol Henarejosa6779282023-02-08 00:50:04 +0100560 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
561 if (result != 0) {
562 if (verbose != 0) {
563 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200564 }
565
566 goto cleanup;
567 }
568
Pol Henarejosa6779282023-02-08 00:50:04 +0100569 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200570 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100571 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200572 break;
573 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100574 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200575 break;
576 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100577 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200578 break;
579 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100580 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200581 break;
582 default:
583 break;
584 }
585
Pol Henarejosa6779282023-02-08 00:50:04 +0100586 if (result != 0) {
587 if (verbose != 0) {
588 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200589 }
590 }
591
Pol Henarejosa6779282023-02-08 00:50:04 +0100592 if (verbose != 0) {
593 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200594 }
595
596cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100597 mbedtls_sha3_free(&ctx);
598 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200599}
600
Pol Henarejosa6779282023-02-08 00:50:04 +0100601int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200602{
603 int i;
604
605 /* SHA3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100606 for (i = 0; i < 2; i++) {
607 if (0 != mbedtls_sha3_kat_test(verbose,
608 "SHA3-224", MBEDTLS_SHA3_224, i)) {
609 return 1;
610 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200611
Pol Henarejosa6779282023-02-08 00:50:04 +0100612 if (0 != mbedtls_sha3_kat_test(verbose,
613 "SHA3-256", MBEDTLS_SHA3_256, i)) {
614 return 1;
615 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200616
Pol Henarejosa6779282023-02-08 00:50:04 +0100617 if (0 != mbedtls_sha3_kat_test(verbose,
618 "SHA3-384", MBEDTLS_SHA3_384, i)) {
619 return 1;
620 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200621
Pol Henarejosa6779282023-02-08 00:50:04 +0100622 if (0 != mbedtls_sha3_kat_test(verbose,
623 "SHA3-512", MBEDTLS_SHA3_512, i)) {
624 return 1;
625 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200626 }
627
628 /* SHA3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100629 if (0 != mbedtls_sha3_long_kat_test(verbose,
630 "SHA3-224", MBEDTLS_SHA3_224)) {
631 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200632 }
633
Pol Henarejosa6779282023-02-08 00:50:04 +0100634 if (0 != mbedtls_sha3_long_kat_test(verbose,
635 "SHA3-256", MBEDTLS_SHA3_256)) {
636 return 1;
637 }
638
639 if (0 != mbedtls_sha3_long_kat_test(verbose,
640 "SHA3-384", MBEDTLS_SHA3_384)) {
641 return 1;
642 }
643
644 if (0 != mbedtls_sha3_long_kat_test(verbose,
645 "SHA3-512", MBEDTLS_SHA3_512)) {
646 return 1;
647 }
648
649 if (verbose != 0) {
650 mbedtls_printf("\n");
651 }
652
653 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200654}
655#endif /* MBEDTLS_SELF_TEST */
656
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200657#endif /* MBEDTLS_SHA3_C */