blob: 7151094452c52661146c0f63063dbaa05d43c49d [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)
83#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
84#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020085
86/* The permutation function. */
87static void keccak_f1600(mbedtls_sha3_context *ctx)
88{
89 uint64_t lane[5];
90 uint64_t *s = ctx->state;
91 int i;
92
Pol Henarejosa6779282023-02-08 00:50:04 +010093 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020094 uint64_t t;
95
96 /* Theta */
97 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
98 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
99 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
100 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
101 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
102
Pol Henarejosa6779282023-02-08 00:50:04 +0100103 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200104 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
105
Pol Henarejosa6779282023-02-08 00:50:04 +0100106 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200107 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
108
Pol Henarejosa6779282023-02-08 00:50:04 +0100109 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200110 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
111
Pol Henarejosa6779282023-02-08 00:50:04 +0100112 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200113 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
114
Pol Henarejosa6779282023-02-08 00:50:04 +0100115 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200116 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
117
118 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +0100119 for (i = 1; i < 25; i++) {
120 s[i] = ROT64(s[i], rho[i-1]);
121 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200122
123 /* Pi */
124 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +0100125 for (i = 0; i < 24; i++) {
126 SWAP(s[pi[i]], t);
127 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200128
129 /* Chi */
130 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
131 s[0] ^= (~lane[1]) & lane[2];
132 s[1] ^= (~lane[2]) & lane[3];
133 s[2] ^= (~lane[3]) & lane[4];
134 s[3] ^= (~lane[4]) & lane[0];
135 s[4] ^= (~lane[0]) & lane[1];
136
137 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
138 s[5] ^= (~lane[1]) & lane[2];
139 s[6] ^= (~lane[2]) & lane[3];
140 s[7] ^= (~lane[3]) & lane[4];
141 s[8] ^= (~lane[4]) & lane[0];
142 s[9] ^= (~lane[0]) & lane[1];
143
144 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
145 s[10] ^= (~lane[1]) & lane[2];
146 s[11] ^= (~lane[2]) & lane[3];
147 s[12] ^= (~lane[3]) & lane[4];
148 s[13] ^= (~lane[4]) & lane[0];
149 s[14] ^= (~lane[0]) & lane[1];
150
151 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
152 s[15] ^= (~lane[1]) & lane[2];
153 s[16] ^= (~lane[2]) & lane[3];
154 s[17] ^= (~lane[3]) & lane[4];
155 s[18] ^= (~lane[4]) & lane[0];
156 s[19] ^= (~lane[0]) & lane[1];
157
158 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
159 s[20] ^= (~lane[1]) & lane[2];
160 s[21] ^= (~lane[2]) & lane[3];
161 s[22] ^= (~lane[3]) & lane[4];
162 s[23] ^= (~lane[4]) & lane[0];
163 s[24] ^= (~lane[0]) & lane[1];
164
165 /* Iota */
166 s[0] ^= rc[round];
167 }
168}
169
Pol Henarejosa6779282023-02-08 00:50:04 +0100170void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200171{
Pol Henarejosa6779282023-02-08 00:50:04 +0100172 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200173}
174
Pol Henarejosa6779282023-02-08 00:50:04 +0100175void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200176{
Pol Henarejosa6779282023-02-08 00:50:04 +0100177 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200178 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100179 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200180
Pol Henarejosa6779282023-02-08 00:50:04 +0100181 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200182}
183
Pol Henarejosa6779282023-02-08 00:50:04 +0100184void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
185 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200186{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200187 *dst = *src;
188}
189
190/*
191 * SHA-3 context setup
192 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100193int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200194{
195 mbedtls_sha3_family_functions *p = NULL;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200196
Pol Henarejosa6779282023-02-08 00:50:04 +0100197 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
198 if (p->id == id) {
199 break;
200 }
201 }
202
203 if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
204 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
205 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200206
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200207 ctx->olen = p->olen / 8;
Dave Rodgman1789d842023-05-29 22:05:19 +0100208 ctx->max_block_size = p->r / 8;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200209
Pol Henarejosa6779282023-02-08 00:50:04 +0100210 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200211 ctx->index = 0;
212
Pol Henarejosa6779282023-02-08 00:50:04 +0100213 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200214}
215
216/*
217 * SHA-3 process buffer
218 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100219int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
220 const uint8_t *input,
221 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200222{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100223 if (ilen >= 8) {
224 // 8-byte align index
225 int align_bytes = 8 - (ctx->index % 8);
226 if (align_bytes) {
227 for (; align_bytes > 0; align_bytes--) {
228 ABSORB(ctx, ctx->index, *input++);
229 ilen--;
230 ctx->index++;
231 }
232 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
233 keccak_f1600(ctx);
234 }
235 }
236
237 // process input in 8-byte chunks
238 while (ilen >= 8) {
Dave Rodgman2f0f9982023-06-07 19:12:04 +0100239 ABSORB(ctx, ctx->index, mbedtls_get_unaligned_uint64(input));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100240 input += 8;
241 ilen -= 8;
242 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
243 keccak_f1600(ctx);
244 }
245 }
246 }
247
248 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100249 while (ilen-- > 0) {
250 ABSORB(ctx, ctx->index, *input++);
251 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
252 keccak_f1600(ctx);
253 }
254 }
255
256 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200257}
258
Pol Henarejosa6779282023-02-08 00:50:04 +0100259int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
260 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200261{
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200262 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100263 if (ctx->olen > 0) {
264 if (ctx->olen > olen) {
265 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
266 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200267 olen = ctx->olen;
268 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200269
Dave Rodgman1789d842023-05-29 22:05:19 +0100270 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100271 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
272 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200273 ctx->index = 0;
274
Pol Henarejosa6779282023-02-08 00:50:04 +0100275 while (olen-- > 0) {
276 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200277
Pol Henarejosa6779282023-02-08 00:50:04 +0100278 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
279 keccak_f1600(ctx);
280 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281 }
282
Pol Henarejosa6779282023-02-08 00:50:04 +0100283 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200284}
285
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100287 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200288 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100289int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
290 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200291{
292 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
293 mbedtls_sha3_context ctx;
294
Pol Henarejosa6779282023-02-08 00:50:04 +0100295 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200296
Pol Henarejos85eeda02022-05-17 11:43:15 +0200297 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100298 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200299 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100300 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200301
Pol Henarejosa6779282023-02-08 00:50:04 +0100302 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200303 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100304 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200305
Pol Henarejosa6779282023-02-08 00:50:04 +0100306 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200307 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100308 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200309
310exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100311 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200312
Pol Henarejosa6779282023-02-08 00:50:04 +0100313 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200314}
315
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200316/**************** Self-tests ****************/
317
318#if defined(MBEDTLS_SELF_TEST)
319
320static const unsigned char test_data[2][4] =
321{
322 "",
323 "abc",
324};
325
326static const size_t test_data_len[2] =
327{
328 0, /* "" */
329 3 /* "abc" */
330};
331
332static const unsigned char test_hash_sha3_224[2][28] =
333{
334 { /* "" */
335 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
336 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
337 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
338 0x5B, 0x5A, 0x6B, 0xC7
339 },
340 { /* "abc" */
341 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
342 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
343 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
344 0x73, 0xB4, 0x6F, 0xDF
345 }
346};
347
348static const unsigned char test_hash_sha3_256[2][32] =
349{
350 { /* "" */
351 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
352 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
353 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
354 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
355 },
356 { /* "abc" */
357 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
358 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
359 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
360 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
361 }
362};
363
364static const unsigned char test_hash_sha3_384[2][48] =
365{
366 { /* "" */
367 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
368 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
369 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
370 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
371 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
372 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
373 },
374 { /* "abc" */
375 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
376 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
377 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
378 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
379 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
380 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
381 }
382};
383
384static const unsigned char test_hash_sha3_512[2][64] =
385{
386 { /* "" */
387 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
388 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
389 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
390 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
391 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
392 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
393 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
394 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
395 },
396 { /* "abc" */
397 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
398 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
399 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
400 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
401 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
402 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
403 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
404 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
405 }
406};
407
408static const unsigned char long_kat_hash_sha3_224[28] =
409{
410 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
411 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
412 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
413 0xA7, 0xFD, 0x65, 0x3C
414};
415
416static const unsigned char long_kat_hash_sha3_256[32] =
417{
418 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
419 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
420 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
421 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
422};
423
424static const unsigned char long_kat_hash_sha3_384[48] =
425{
426 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
427 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
428 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
429 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
430 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
431 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
432};
433
434static const unsigned char long_kat_hash_sha3_512[64] =
435{
436 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
437 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
438 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
439 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
440 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
441 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
442 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
443 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
444};
445
Pol Henarejosa6779282023-02-08 00:50:04 +0100446static int mbedtls_sha3_kat_test(int verbose,
447 const char *type_name,
448 mbedtls_sha3_id id,
449 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200450{
451 uint8_t hash[64];
452 int result;
453
Pol Henarejosa6779282023-02-08 00:50:04 +0100454 result = mbedtls_sha3(id,
455 test_data[test_num], test_data_len[test_num],
456 hash, sizeof(hash));
457 if (result != 0) {
458 if (verbose != 0) {
459 mbedtls_printf(" %s test %d error code: %d\n",
460 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200461 }
462
Pol Henarejosa6779282023-02-08 00:50:04 +0100463 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200464 }
465
Pol Henarejosa6779282023-02-08 00:50:04 +0100466 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200467 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100468 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200469 break;
470 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100471 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200472 break;
473 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100474 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200475 break;
476 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100477 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200478 break;
479 default:
480 break;
481 }
482
Pol Henarejosa6779282023-02-08 00:50:04 +0100483 if (0 != result) {
484 if (verbose != 0) {
485 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200486 }
487
Pol Henarejosa6779282023-02-08 00:50:04 +0100488 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200489 }
490
Pol Henarejosa6779282023-02-08 00:50:04 +0100491 if (verbose != 0) {
492 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200493 }
494
Pol Henarejosa6779282023-02-08 00:50:04 +0100495 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200496}
497
Pol Henarejosa6779282023-02-08 00:50:04 +0100498static int mbedtls_sha3_long_kat_test(int verbose,
499 const char *type_name,
500 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200501{
502 mbedtls_sha3_context ctx;
503 unsigned char buffer[1000];
504 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200505 int result = 0;
506
Pol Henarejosa6779282023-02-08 00:50:04 +0100507 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200508
Pol Henarejosa6779282023-02-08 00:50:04 +0100509 if (verbose != 0) {
510 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200511 }
512
Pol Henarejosa6779282023-02-08 00:50:04 +0100513 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200514
Pol Henarejosa6779282023-02-08 00:50:04 +0100515 result = mbedtls_sha3_starts(&ctx, id);
516 if (result != 0) {
517 if (verbose != 0) {
518 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200519 }
520 }
521
522 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100523 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100524 result = mbedtls_sha3_update(&ctx, buffer, 1000);
525 if (result != 0) {
526 if (verbose != 0) {
527 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200528 }
529
530 goto cleanup;
531 }
532 }
533
Pol Henarejosa6779282023-02-08 00:50:04 +0100534 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
535 if (result != 0) {
536 if (verbose != 0) {
537 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200538 }
539
540 goto cleanup;
541 }
542
Pol Henarejosa6779282023-02-08 00:50:04 +0100543 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200544 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100545 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200546 break;
547 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100548 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200549 break;
550 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100551 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200552 break;
553 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100554 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200555 break;
556 default:
557 break;
558 }
559
Pol Henarejosa6779282023-02-08 00:50:04 +0100560 if (result != 0) {
561 if (verbose != 0) {
562 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200563 }
564 }
565
Pol Henarejosa6779282023-02-08 00:50:04 +0100566 if (verbose != 0) {
567 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200568 }
569
570cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100571 mbedtls_sha3_free(&ctx);
572 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200573}
574
Pol Henarejosa6779282023-02-08 00:50:04 +0100575int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200576{
577 int i;
578
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100579 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100580 for (i = 0; i < 2; i++) {
581 if (0 != mbedtls_sha3_kat_test(verbose,
582 "SHA3-224", MBEDTLS_SHA3_224, i)) {
583 return 1;
584 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200585
Pol Henarejosa6779282023-02-08 00:50:04 +0100586 if (0 != mbedtls_sha3_kat_test(verbose,
587 "SHA3-256", MBEDTLS_SHA3_256, i)) {
588 return 1;
589 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200590
Pol Henarejosa6779282023-02-08 00:50:04 +0100591 if (0 != mbedtls_sha3_kat_test(verbose,
592 "SHA3-384", MBEDTLS_SHA3_384, i)) {
593 return 1;
594 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200595
Pol Henarejosa6779282023-02-08 00:50:04 +0100596 if (0 != mbedtls_sha3_kat_test(verbose,
597 "SHA3-512", MBEDTLS_SHA3_512, i)) {
598 return 1;
599 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200600 }
601
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100602 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100603 if (0 != mbedtls_sha3_long_kat_test(verbose,
604 "SHA3-224", MBEDTLS_SHA3_224)) {
605 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200606 }
607
Pol Henarejosa6779282023-02-08 00:50:04 +0100608 if (0 != mbedtls_sha3_long_kat_test(verbose,
609 "SHA3-256", MBEDTLS_SHA3_256)) {
610 return 1;
611 }
612
613 if (0 != mbedtls_sha3_long_kat_test(verbose,
614 "SHA3-384", MBEDTLS_SHA3_384)) {
615 return 1;
616 }
617
618 if (0 != mbedtls_sha3_long_kat_test(verbose,
619 "SHA3-512", MBEDTLS_SHA3_512)) {
620 return 1;
621 }
622
623 if (verbose != 0) {
624 mbedtls_printf("\n");
625 }
626
627 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200628}
629#endif /* MBEDTLS_SELF_TEST */
630
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200631#endif /* MBEDTLS_SHA3_C */