blob: b8abf9d32137e80924755f3db6472ddae7b6104d [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
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020041/*
42 * List of supported SHA-3 families
43 */
44static mbedtls_sha3_family_functions sha3_families[] = {
Dave Rodgman1789d842023-05-29 22:05:19 +010045 { MBEDTLS_SHA3_224, 1152, 224 },
46 { MBEDTLS_SHA3_256, 1088, 256 },
47 { MBEDTLS_SHA3_384, 832, 384 },
48 { MBEDTLS_SHA3_512, 576, 512 },
49 { MBEDTLS_SHA3_NONE, 0, 0 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020050};
51
52static const uint64_t rc[24] = {
53 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
54 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
55 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
56 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
57 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
58 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
59};
60
61static const uint8_t rho[24] = {
62 1, 62, 28, 27, 36, 44, 6, 55, 20,
63 3, 10, 43, 25, 39, 41, 45, 15,
64 21, 8, 18, 2, 61, 56, 14
65};
66
67static const uint8_t pi[24] = {
68 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
69 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
70};
71
Pol Henarejosa6779282023-02-08 00:50:04 +010072#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
73#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
74} while (0)
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +010075#define ABSORB8(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << ((idx) << 3); \
76} while (0)
Pol Henarejosa6779282023-02-08 00:50:04 +010077#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
78#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020079
80/* The permutation function. */
81static void keccak_f1600(mbedtls_sha3_context *ctx)
82{
83 uint64_t lane[5];
84 uint64_t *s = ctx->state;
85 int i;
86
Pol Henarejosa6779282023-02-08 00:50:04 +010087 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020088 uint64_t t;
89
90 /* Theta */
91 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
92 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
93 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
94 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
95 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
96
Pol Henarejosa6779282023-02-08 00:50:04 +010097 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020098 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
99
Pol Henarejosa6779282023-02-08 00:50:04 +0100100 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200101 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
102
Pol Henarejosa6779282023-02-08 00:50:04 +0100103 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200104 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
105
Pol Henarejosa6779282023-02-08 00:50:04 +0100106 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200107 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
108
Pol Henarejosa6779282023-02-08 00:50:04 +0100109 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200110 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
111
112 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +0100113 for (i = 1; i < 25; i++) {
114 s[i] = ROT64(s[i], rho[i-1]);
115 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200116
117 /* Pi */
118 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +0100119 for (i = 0; i < 24; i++) {
120 SWAP(s[pi[i]], t);
121 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200122
123 /* Chi */
124 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
125 s[0] ^= (~lane[1]) & lane[2];
126 s[1] ^= (~lane[2]) & lane[3];
127 s[2] ^= (~lane[3]) & lane[4];
128 s[3] ^= (~lane[4]) & lane[0];
129 s[4] ^= (~lane[0]) & lane[1];
130
131 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
132 s[5] ^= (~lane[1]) & lane[2];
133 s[6] ^= (~lane[2]) & lane[3];
134 s[7] ^= (~lane[3]) & lane[4];
135 s[8] ^= (~lane[4]) & lane[0];
136 s[9] ^= (~lane[0]) & lane[1];
137
138 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
139 s[10] ^= (~lane[1]) & lane[2];
140 s[11] ^= (~lane[2]) & lane[3];
141 s[12] ^= (~lane[3]) & lane[4];
142 s[13] ^= (~lane[4]) & lane[0];
143 s[14] ^= (~lane[0]) & lane[1];
144
145 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
146 s[15] ^= (~lane[1]) & lane[2];
147 s[16] ^= (~lane[2]) & lane[3];
148 s[17] ^= (~lane[3]) & lane[4];
149 s[18] ^= (~lane[4]) & lane[0];
150 s[19] ^= (~lane[0]) & lane[1];
151
152 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
153 s[20] ^= (~lane[1]) & lane[2];
154 s[21] ^= (~lane[2]) & lane[3];
155 s[22] ^= (~lane[3]) & lane[4];
156 s[23] ^= (~lane[4]) & lane[0];
157 s[24] ^= (~lane[0]) & lane[1];
158
159 /* Iota */
160 s[0] ^= rc[round];
161 }
162}
163
Pol Henarejosa6779282023-02-08 00:50:04 +0100164void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200165{
Pol Henarejosa6779282023-02-08 00:50:04 +0100166 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200167 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100168 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200169
Pol Henarejosa6779282023-02-08 00:50:04 +0100170 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200171}
172
Pol Henarejosa6779282023-02-08 00:50:04 +0100173void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200174{
Pol Henarejosa6779282023-02-08 00:50:04 +0100175 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200176 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100177 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200178
Pol Henarejosa6779282023-02-08 00:50:04 +0100179 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200180}
181
Pol Henarejosa6779282023-02-08 00:50:04 +0100182void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
183 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200184{
Pol Henarejosa6779282023-02-08 00:50:04 +0100185 if (dst == NULL || src == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200186 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100187 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200188
189 *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 Henarejosa6779282023-02-08 00:50:04 +0100198 if (ctx == NULL) {
199 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200200 }
201
Pol Henarejosa6779282023-02-08 00:50:04 +0100202 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
203 if (p->id == id) {
204 break;
205 }
206 }
207
208 if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
209 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
210 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200211
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200212 ctx->olen = p->olen / 8;
Dave Rodgman1789d842023-05-29 22:05:19 +0100213 ctx->max_block_size = p->r / 8;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200214
Pol Henarejosa6779282023-02-08 00:50:04 +0100215 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200216 ctx->index = 0;
217
Pol Henarejosa6779282023-02-08 00:50:04 +0100218 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200219}
220
221/*
222 * SHA-3 process buffer
223 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100224int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
225 const uint8_t *input,
226 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200227{
Pol Henarejosa6779282023-02-08 00:50:04 +0100228 if (ctx == NULL) {
229 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200230 }
231
Pol Henarejosa6779282023-02-08 00:50:04 +0100232 if (ilen == 0 || input == NULL) {
233 return 0;
234 }
235
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100236 if (ilen >= 8) {
237 // 8-byte align index
238 int align_bytes = 8 - (ctx->index % 8);
239 if (align_bytes) {
240 for (; align_bytes > 0; align_bytes--) {
241 ABSORB(ctx, ctx->index, *input++);
242 ilen--;
243 ctx->index++;
244 }
245 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
246 keccak_f1600(ctx);
247 }
248 }
249
250 // process input in 8-byte chunks
251 while (ilen >= 8) {
252 ABSORB8(ctx, ctx->index, mbedtls_get_unaligned_uint64(input));
253 input += 8;
254 ilen -= 8;
255 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
256 keccak_f1600(ctx);
257 }
258 }
259 }
260
261 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100262 while (ilen-- > 0) {
263 ABSORB(ctx, ctx->index, *input++);
264 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
265 keccak_f1600(ctx);
266 }
267 }
268
269 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200270}
271
Pol Henarejosa6779282023-02-08 00:50:04 +0100272int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
273 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200274{
Pol Henarejosa6779282023-02-08 00:50:04 +0100275 if (ctx == NULL || output == NULL) {
276 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
277 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200278
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200279 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100280 if (ctx->olen > 0) {
281 if (ctx->olen > olen) {
282 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
283 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200284 olen = ctx->olen;
285 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286
Dave Rodgman1789d842023-05-29 22:05:19 +0100287 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100288 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
289 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200290 ctx->index = 0;
291
Pol Henarejosa6779282023-02-08 00:50:04 +0100292 while (olen-- > 0) {
293 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200294
Pol Henarejosa6779282023-02-08 00:50:04 +0100295 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
296 keccak_f1600(ctx);
297 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200298 }
299
Pol Henarejosa6779282023-02-08 00:50:04 +0100300 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200301}
302
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200303/*
304 * output = SHA3( input buffer )
305 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100306int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
307 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200308{
309 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
310 mbedtls_sha3_context ctx;
311
Pol Henarejosa6779282023-02-08 00:50:04 +0100312 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200313
Pol Henarejos85eeda02022-05-17 11:43:15 +0200314 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100315 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200316 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100317 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200318
Pol Henarejosa6779282023-02-08 00:50:04 +0100319 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200320 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100321 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200322
Pol Henarejosa6779282023-02-08 00:50:04 +0100323 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 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
327exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100328 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200329
Pol Henarejosa6779282023-02-08 00:50:04 +0100330 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200331}
332
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200333/**************** Self-tests ****************/
334
335#if defined(MBEDTLS_SELF_TEST)
336
337static const unsigned char test_data[2][4] =
338{
339 "",
340 "abc",
341};
342
343static const size_t test_data_len[2] =
344{
345 0, /* "" */
346 3 /* "abc" */
347};
348
349static const unsigned char test_hash_sha3_224[2][28] =
350{
351 { /* "" */
352 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
353 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
354 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
355 0x5B, 0x5A, 0x6B, 0xC7
356 },
357 { /* "abc" */
358 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
359 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
360 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
361 0x73, 0xB4, 0x6F, 0xDF
362 }
363};
364
365static const unsigned char test_hash_sha3_256[2][32] =
366{
367 { /* "" */
368 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
369 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
370 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
371 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
372 },
373 { /* "abc" */
374 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
375 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
376 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
377 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
378 }
379};
380
381static const unsigned char test_hash_sha3_384[2][48] =
382{
383 { /* "" */
384 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
385 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
386 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
387 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
388 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
389 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
390 },
391 { /* "abc" */
392 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
393 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
394 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
395 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
396 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
397 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
398 }
399};
400
401static const unsigned char test_hash_sha3_512[2][64] =
402{
403 { /* "" */
404 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
405 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
406 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
407 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
408 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
409 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
410 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
411 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
412 },
413 { /* "abc" */
414 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
415 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
416 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
417 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
418 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
419 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
420 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
421 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
422 }
423};
424
425static const unsigned char long_kat_hash_sha3_224[28] =
426{
427 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
428 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
429 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
430 0xA7, 0xFD, 0x65, 0x3C
431};
432
433static const unsigned char long_kat_hash_sha3_256[32] =
434{
435 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
436 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
437 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
438 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
439};
440
441static const unsigned char long_kat_hash_sha3_384[48] =
442{
443 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
444 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
445 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
446 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
447 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
448 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
449};
450
451static const unsigned char long_kat_hash_sha3_512[64] =
452{
453 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
454 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
455 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
456 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
457 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
458 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
459 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
460 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
461};
462
Pol Henarejosa6779282023-02-08 00:50:04 +0100463static int mbedtls_sha3_kat_test(int verbose,
464 const char *type_name,
465 mbedtls_sha3_id id,
466 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200467{
468 uint8_t hash[64];
469 int result;
470
Pol Henarejosa6779282023-02-08 00:50:04 +0100471 result = mbedtls_sha3(id,
472 test_data[test_num], test_data_len[test_num],
473 hash, sizeof(hash));
474 if (result != 0) {
475 if (verbose != 0) {
476 mbedtls_printf(" %s test %d error code: %d\n",
477 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200478 }
479
Pol Henarejosa6779282023-02-08 00:50:04 +0100480 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200481 }
482
Pol Henarejosa6779282023-02-08 00:50:04 +0100483 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200484 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100485 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200486 break;
487 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100488 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200489 break;
490 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100491 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200492 break;
493 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100494 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200495 break;
496 default:
497 break;
498 }
499
Pol Henarejosa6779282023-02-08 00:50:04 +0100500 if (0 != result) {
501 if (verbose != 0) {
502 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503 }
504
Pol Henarejosa6779282023-02-08 00:50:04 +0100505 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200506 }
507
Pol Henarejosa6779282023-02-08 00:50:04 +0100508 if (verbose != 0) {
509 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200510 }
511
Pol Henarejosa6779282023-02-08 00:50:04 +0100512 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200513}
514
Pol Henarejosa6779282023-02-08 00:50:04 +0100515static int mbedtls_sha3_long_kat_test(int verbose,
516 const char *type_name,
517 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200518{
519 mbedtls_sha3_context ctx;
520 unsigned char buffer[1000];
521 unsigned char hash[64];
522 int i;
523 int result = 0;
524
Pol Henarejosa6779282023-02-08 00:50:04 +0100525 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200526
Pol Henarejosa6779282023-02-08 00:50:04 +0100527 if (verbose != 0) {
528 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200529 }
530
Pol Henarejosa6779282023-02-08 00:50:04 +0100531 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200532
Pol Henarejosa6779282023-02-08 00:50:04 +0100533 result = mbedtls_sha3_starts(&ctx, id);
534 if (result != 0) {
535 if (verbose != 0) {
536 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200537 }
538 }
539
540 /* Process 1,000,000 (one million) 'a' characters */
Pol Henarejosa6779282023-02-08 00:50:04 +0100541 for (i = 0; i < 1000; i++) {
542 result = mbedtls_sha3_update(&ctx, buffer, 1000);
543 if (result != 0) {
544 if (verbose != 0) {
545 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200546 }
547
548 goto cleanup;
549 }
550 }
551
Pol Henarejosa6779282023-02-08 00:50:04 +0100552 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
553 if (result != 0) {
554 if (verbose != 0) {
555 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200556 }
557
558 goto cleanup;
559 }
560
Pol Henarejosa6779282023-02-08 00:50:04 +0100561 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200562 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100563 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200564 break;
565 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100566 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200567 break;
568 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100569 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200570 break;
571 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100572 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200573 break;
574 default:
575 break;
576 }
577
Pol Henarejosa6779282023-02-08 00:50:04 +0100578 if (result != 0) {
579 if (verbose != 0) {
580 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200581 }
582 }
583
Pol Henarejosa6779282023-02-08 00:50:04 +0100584 if (verbose != 0) {
585 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200586 }
587
588cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100589 mbedtls_sha3_free(&ctx);
590 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200591}
592
Pol Henarejosa6779282023-02-08 00:50:04 +0100593int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200594{
595 int i;
596
597 /* SHA3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100598 for (i = 0; i < 2; i++) {
599 if (0 != mbedtls_sha3_kat_test(verbose,
600 "SHA3-224", MBEDTLS_SHA3_224, i)) {
601 return 1;
602 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200603
Pol Henarejosa6779282023-02-08 00:50:04 +0100604 if (0 != mbedtls_sha3_kat_test(verbose,
605 "SHA3-256", MBEDTLS_SHA3_256, i)) {
606 return 1;
607 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200608
Pol Henarejosa6779282023-02-08 00:50:04 +0100609 if (0 != mbedtls_sha3_kat_test(verbose,
610 "SHA3-384", MBEDTLS_SHA3_384, i)) {
611 return 1;
612 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200613
Pol Henarejosa6779282023-02-08 00:50:04 +0100614 if (0 != mbedtls_sha3_kat_test(verbose,
615 "SHA3-512", MBEDTLS_SHA3_512, i)) {
616 return 1;
617 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200618 }
619
620 /* SHA3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100621 if (0 != mbedtls_sha3_long_kat_test(verbose,
622 "SHA3-224", MBEDTLS_SHA3_224)) {
623 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200624 }
625
Pol Henarejosa6779282023-02-08 00:50:04 +0100626 if (0 != mbedtls_sha3_long_kat_test(verbose,
627 "SHA3-256", MBEDTLS_SHA3_256)) {
628 return 1;
629 }
630
631 if (0 != mbedtls_sha3_long_kat_test(verbose,
632 "SHA3-384", MBEDTLS_SHA3_384)) {
633 return 1;
634 }
635
636 if (0 != mbedtls_sha3_long_kat_test(verbose,
637 "SHA3-512", MBEDTLS_SHA3_512)) {
638 return 1;
639 }
640
641 if (verbose != 0) {
642 mbedtls_printf("\n");
643 }
644
645 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200646}
647#endif /* MBEDTLS_SELF_TEST */
648
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200649#endif /* MBEDTLS_SHA3_C */