blob: d875b8185b0773ca1a10ed80b208d0f4cabdaabc [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
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020039/*
40 * List of supported SHA-3 families
41 */
42static mbedtls_sha3_family_functions sha3_families[] = {
43 { MBEDTLS_SHA3_224, 1152, 224, 0x06 },
44 { MBEDTLS_SHA3_256, 1088, 256, 0x06 },
45 { MBEDTLS_SHA3_384, 832, 384, 0x06 },
46 { MBEDTLS_SHA3_512, 576, 512, 0x06 },
47 { MBEDTLS_SHA3_NONE, 0, 0, 0 }
48};
49
50static const uint64_t rc[24] = {
51 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
52 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
53 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
54 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
55 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
56 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
57};
58
59static const uint8_t rho[24] = {
60 1, 62, 28, 27, 36, 44, 6, 55, 20,
61 3, 10, 43, 25, 39, 41, 45, 15,
62 21, 8, 18, 2, 61, 56, 14
63};
64
65static const uint8_t pi[24] = {
66 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
67 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
68};
69
Pol Henarejosa6779282023-02-08 00:50:04 +010070#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
71#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
72} while (0)
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +010073#define ABSORB8(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << ((idx) << 3); \
74} while (0)
Pol Henarejosa6779282023-02-08 00:50:04 +010075#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
76#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020077
78/* The permutation function. */
79static void keccak_f1600(mbedtls_sha3_context *ctx)
80{
81 uint64_t lane[5];
82 uint64_t *s = ctx->state;
83 int i;
84
Pol Henarejosa6779282023-02-08 00:50:04 +010085 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020086 uint64_t t;
87
88 /* Theta */
89 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
90 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
91 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
92 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
93 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
94
Pol Henarejosa6779282023-02-08 00:50:04 +010095 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020096 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
97
Pol Henarejosa6779282023-02-08 00:50:04 +010098 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020099 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
100
Pol Henarejosa6779282023-02-08 00:50:04 +0100101 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200102 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
103
Pol Henarejosa6779282023-02-08 00:50:04 +0100104 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200105 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
106
Pol Henarejosa6779282023-02-08 00:50:04 +0100107 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200108 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
109
110 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +0100111 for (i = 1; i < 25; i++) {
112 s[i] = ROT64(s[i], rho[i-1]);
113 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200114
115 /* Pi */
116 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +0100117 for (i = 0; i < 24; i++) {
118 SWAP(s[pi[i]], t);
119 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200120
121 /* Chi */
122 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
123 s[0] ^= (~lane[1]) & lane[2];
124 s[1] ^= (~lane[2]) & lane[3];
125 s[2] ^= (~lane[3]) & lane[4];
126 s[3] ^= (~lane[4]) & lane[0];
127 s[4] ^= (~lane[0]) & lane[1];
128
129 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
130 s[5] ^= (~lane[1]) & lane[2];
131 s[6] ^= (~lane[2]) & lane[3];
132 s[7] ^= (~lane[3]) & lane[4];
133 s[8] ^= (~lane[4]) & lane[0];
134 s[9] ^= (~lane[0]) & lane[1];
135
136 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
137 s[10] ^= (~lane[1]) & lane[2];
138 s[11] ^= (~lane[2]) & lane[3];
139 s[12] ^= (~lane[3]) & lane[4];
140 s[13] ^= (~lane[4]) & lane[0];
141 s[14] ^= (~lane[0]) & lane[1];
142
143 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
144 s[15] ^= (~lane[1]) & lane[2];
145 s[16] ^= (~lane[2]) & lane[3];
146 s[17] ^= (~lane[3]) & lane[4];
147 s[18] ^= (~lane[4]) & lane[0];
148 s[19] ^= (~lane[0]) & lane[1];
149
150 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
151 s[20] ^= (~lane[1]) & lane[2];
152 s[21] ^= (~lane[2]) & lane[3];
153 s[22] ^= (~lane[3]) & lane[4];
154 s[23] ^= (~lane[4]) & lane[0];
155 s[24] ^= (~lane[0]) & lane[1];
156
157 /* Iota */
158 s[0] ^= rc[round];
159 }
160}
161
Pol Henarejosa6779282023-02-08 00:50:04 +0100162void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200163{
Pol Henarejosa6779282023-02-08 00:50:04 +0100164 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200165 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100166 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200167
Pol Henarejosa6779282023-02-08 00:50:04 +0100168 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200169}
170
Pol Henarejosa6779282023-02-08 00:50:04 +0100171void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200172{
Pol Henarejosa6779282023-02-08 00:50:04 +0100173 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200174 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100175 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200176
Pol Henarejosa6779282023-02-08 00:50:04 +0100177 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200178}
179
Pol Henarejosa6779282023-02-08 00:50:04 +0100180void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
181 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200182{
Pol Henarejosa6779282023-02-08 00:50:04 +0100183 if (dst == NULL || src == 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
187 *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 Henarejosa6779282023-02-08 00:50:04 +0100196 if (ctx == NULL) {
197 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200198 }
199
Pol Henarejosa6779282023-02-08 00:50:04 +0100200 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
201 if (p->id == id) {
202 break;
203 }
204 }
205
206 if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
207 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
208 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200209
210 ctx->id = id;
211 ctx->r = p->r;
212 ctx->olen = p->olen / 8;
213 ctx->xor_byte = p->xor_byte;
214 ctx->max_block_size = ctx->r / 8;
215
Pol Henarejosa6779282023-02-08 00:50:04 +0100216 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200217 ctx->index = 0;
218
Pol Henarejosa6779282023-02-08 00:50:04 +0100219 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200220}
221
222/*
223 * SHA-3 process buffer
224 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100225int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
226 const uint8_t *input,
227 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200228{
Pol Henarejosa6779282023-02-08 00:50:04 +0100229 if (ctx == NULL) {
230 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200231 }
232
Pol Henarejosa6779282023-02-08 00:50:04 +0100233 if (ilen == 0 || input == NULL) {
234 return 0;
235 }
236
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100237 if (ilen >= 8) {
238 // 8-byte align index
239 int align_bytes = 8 - (ctx->index % 8);
240 if (align_bytes) {
241 for (; align_bytes > 0; align_bytes--) {
242 ABSORB(ctx, ctx->index, *input++);
243 ilen--;
244 ctx->index++;
245 }
246 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
247 keccak_f1600(ctx);
248 }
249 }
250
251 // process input in 8-byte chunks
252 while (ilen >= 8) {
253 ABSORB8(ctx, ctx->index, mbedtls_get_unaligned_uint64(input));
254 input += 8;
255 ilen -= 8;
256 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
257 keccak_f1600(ctx);
258 }
259 }
260 }
261
262 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100263 while (ilen-- > 0) {
264 ABSORB(ctx, ctx->index, *input++);
265 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
266 keccak_f1600(ctx);
267 }
268 }
269
270 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200271}
272
Pol Henarejosa6779282023-02-08 00:50:04 +0100273int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
274 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200275{
Pol Henarejosa6779282023-02-08 00:50:04 +0100276 if (ctx == NULL || output == NULL) {
277 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
278 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200279
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200280 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100281 if (ctx->olen > 0) {
282 if (ctx->olen > olen) {
283 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
284 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200285 olen = ctx->olen;
286 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200287
Pol Henarejosa6779282023-02-08 00:50:04 +0100288 ABSORB(ctx, ctx->index, ctx->xor_byte);
289 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
290 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200291 ctx->index = 0;
292
Pol Henarejosa6779282023-02-08 00:50:04 +0100293 while (olen-- > 0) {
294 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200295
Pol Henarejosa6779282023-02-08 00:50:04 +0100296 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
297 keccak_f1600(ctx);
298 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200299 }
300
Pol Henarejosa6779282023-02-08 00:50:04 +0100301 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200302}
303
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200304/*
305 * output = SHA3( input buffer )
306 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100307int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
308 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200309{
310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
311 mbedtls_sha3_context ctx;
312
Pol Henarejosa6779282023-02-08 00:50:04 +0100313 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200314
Pol Henarejos85eeda02022-05-17 11:43:15 +0200315 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100316 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200317 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100318 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200319
Pol Henarejosa6779282023-02-08 00:50:04 +0100320 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200321 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100322 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200323
Pol Henarejosa6779282023-02-08 00:50:04 +0100324 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200325 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100326 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200327
328exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100329 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200330
Pol Henarejosa6779282023-02-08 00:50:04 +0100331 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200332}
333
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200334/**************** Self-tests ****************/
335
336#if defined(MBEDTLS_SELF_TEST)
337
338static const unsigned char test_data[2][4] =
339{
340 "",
341 "abc",
342};
343
344static const size_t test_data_len[2] =
345{
346 0, /* "" */
347 3 /* "abc" */
348};
349
350static const unsigned char test_hash_sha3_224[2][28] =
351{
352 { /* "" */
353 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
354 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
355 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
356 0x5B, 0x5A, 0x6B, 0xC7
357 },
358 { /* "abc" */
359 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
360 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
361 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
362 0x73, 0xB4, 0x6F, 0xDF
363 }
364};
365
366static const unsigned char test_hash_sha3_256[2][32] =
367{
368 { /* "" */
369 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
370 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
371 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
372 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
373 },
374 { /* "abc" */
375 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
376 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
377 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
378 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
379 }
380};
381
382static const unsigned char test_hash_sha3_384[2][48] =
383{
384 { /* "" */
385 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
386 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
387 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
388 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
389 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
390 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
391 },
392 { /* "abc" */
393 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
394 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
395 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
396 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
397 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
398 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
399 }
400};
401
402static const unsigned char test_hash_sha3_512[2][64] =
403{
404 { /* "" */
405 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
406 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
407 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
408 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
409 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
410 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
411 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
412 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
413 },
414 { /* "abc" */
415 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
416 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
417 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
418 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
419 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
420 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
421 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
422 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
423 }
424};
425
426static const unsigned char long_kat_hash_sha3_224[28] =
427{
428 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
429 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
430 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
431 0xA7, 0xFD, 0x65, 0x3C
432};
433
434static const unsigned char long_kat_hash_sha3_256[32] =
435{
436 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
437 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
438 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
439 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
440};
441
442static const unsigned char long_kat_hash_sha3_384[48] =
443{
444 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
445 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
446 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
447 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
448 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
449 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
450};
451
452static const unsigned char long_kat_hash_sha3_512[64] =
453{
454 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
455 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
456 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
457 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
458 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
459 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
460 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
461 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
462};
463
Pol Henarejosa6779282023-02-08 00:50:04 +0100464static int mbedtls_sha3_kat_test(int verbose,
465 const char *type_name,
466 mbedtls_sha3_id id,
467 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200468{
469 uint8_t hash[64];
470 int result;
471
Pol Henarejosa6779282023-02-08 00:50:04 +0100472 result = mbedtls_sha3(id,
473 test_data[test_num], test_data_len[test_num],
474 hash, sizeof(hash));
475 if (result != 0) {
476 if (verbose != 0) {
477 mbedtls_printf(" %s test %d error code: %d\n",
478 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200479 }
480
Pol Henarejosa6779282023-02-08 00:50:04 +0100481 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200482 }
483
Pol Henarejosa6779282023-02-08 00:50:04 +0100484 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200485 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100486 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200487 break;
488 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100489 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200490 break;
491 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100492 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200493 break;
494 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100495 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200496 break;
497 default:
498 break;
499 }
500
Pol Henarejosa6779282023-02-08 00:50:04 +0100501 if (0 != result) {
502 if (verbose != 0) {
503 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200504 }
505
Pol Henarejosa6779282023-02-08 00:50:04 +0100506 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200507 }
508
Pol Henarejosa6779282023-02-08 00:50:04 +0100509 if (verbose != 0) {
510 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200511 }
512
Pol Henarejosa6779282023-02-08 00:50:04 +0100513 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200514}
515
Pol Henarejosa6779282023-02-08 00:50:04 +0100516static int mbedtls_sha3_long_kat_test(int verbose,
517 const char *type_name,
518 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200519{
520 mbedtls_sha3_context ctx;
521 unsigned char buffer[1000];
522 unsigned char hash[64];
523 int i;
524 int result = 0;
525
Pol Henarejosa6779282023-02-08 00:50:04 +0100526 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200527
Pol Henarejosa6779282023-02-08 00:50:04 +0100528 if (verbose != 0) {
529 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200530 }
531
Pol Henarejosa6779282023-02-08 00:50:04 +0100532 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200533
Pol Henarejosa6779282023-02-08 00:50:04 +0100534 result = mbedtls_sha3_starts(&ctx, id);
535 if (result != 0) {
536 if (verbose != 0) {
537 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200538 }
539 }
540
541 /* Process 1,000,000 (one million) 'a' characters */
Pol Henarejosa6779282023-02-08 00:50:04 +0100542 for (i = 0; i < 1000; i++) {
543 result = mbedtls_sha3_update(&ctx, buffer, 1000);
544 if (result != 0) {
545 if (verbose != 0) {
546 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200547 }
548
549 goto cleanup;
550 }
551 }
552
Pol Henarejosa6779282023-02-08 00:50:04 +0100553 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
554 if (result != 0) {
555 if (verbose != 0) {
556 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200557 }
558
559 goto cleanup;
560 }
561
Pol Henarejosa6779282023-02-08 00:50:04 +0100562 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200563 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100564 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200565 break;
566 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100567 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200568 break;
569 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100570 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200571 break;
572 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100573 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200574 break;
575 default:
576 break;
577 }
578
Pol Henarejosa6779282023-02-08 00:50:04 +0100579 if (result != 0) {
580 if (verbose != 0) {
581 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200582 }
583 }
584
Pol Henarejosa6779282023-02-08 00:50:04 +0100585 if (verbose != 0) {
586 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200587 }
588
589cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100590 mbedtls_sha3_free(&ctx);
591 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200592}
593
Pol Henarejosa6779282023-02-08 00:50:04 +0100594int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200595{
596 int i;
597
598 /* SHA3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100599 for (i = 0; i < 2; i++) {
600 if (0 != mbedtls_sha3_kat_test(verbose,
601 "SHA3-224", MBEDTLS_SHA3_224, i)) {
602 return 1;
603 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200604
Pol Henarejosa6779282023-02-08 00:50:04 +0100605 if (0 != mbedtls_sha3_kat_test(verbose,
606 "SHA3-256", MBEDTLS_SHA3_256, i)) {
607 return 1;
608 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200609
Pol Henarejosa6779282023-02-08 00:50:04 +0100610 if (0 != mbedtls_sha3_kat_test(verbose,
611 "SHA3-384", MBEDTLS_SHA3_384, i)) {
612 return 1;
613 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200614
Pol Henarejosa6779282023-02-08 00:50:04 +0100615 if (0 != mbedtls_sha3_kat_test(verbose,
616 "SHA3-512", MBEDTLS_SHA3_512, i)) {
617 return 1;
618 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200619 }
620
621 /* SHA3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100622 if (0 != mbedtls_sha3_long_kat_test(verbose,
623 "SHA3-224", MBEDTLS_SHA3_224)) {
624 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200625 }
626
Pol Henarejosa6779282023-02-08 00:50:04 +0100627 if (0 != mbedtls_sha3_long_kat_test(verbose,
628 "SHA3-256", MBEDTLS_SHA3_256)) {
629 return 1;
630 }
631
632 if (0 != mbedtls_sha3_long_kat_test(verbose,
633 "SHA3-384", MBEDTLS_SHA3_384)) {
634 return 1;
635 }
636
637 if (0 != mbedtls_sha3_long_kat_test(verbose,
638 "SHA3-512", MBEDTLS_SHA3_512)) {
639 return 1;
640 }
641
642 if (verbose != 0) {
643 mbedtls_printf("\n");
644 }
645
646 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200647}
648#endif /* MBEDTLS_SELF_TEST */
649
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200650#endif /* MBEDTLS_SHA3_C */