blob: 959928e9da9ea520d409618537e760fe2dad792b [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)
73#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
74#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020075
76/* The permutation function. */
77static void keccak_f1600(mbedtls_sha3_context *ctx)
78{
79 uint64_t lane[5];
80 uint64_t *s = ctx->state;
81 int i;
82
Pol Henarejosa6779282023-02-08 00:50:04 +010083 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020084 uint64_t t;
85
86 /* Theta */
87 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
88 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
89 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
90 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
91 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
92
Pol Henarejosa6779282023-02-08 00:50:04 +010093 t = lane[4] ^ ROT64(lane[1], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020094 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
95
Pol Henarejosa6779282023-02-08 00:50:04 +010096 t = lane[0] ^ ROT64(lane[2], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020097 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
98
Pol Henarejosa6779282023-02-08 00:50:04 +010099 t = lane[1] ^ ROT64(lane[3], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200100 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
101
Pol Henarejosa6779282023-02-08 00:50:04 +0100102 t = lane[2] ^ ROT64(lane[4], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200103 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
104
Pol Henarejosa6779282023-02-08 00:50:04 +0100105 t = lane[3] ^ ROT64(lane[0], 1);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200106 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
107
108 /* Rho */
Pol Henarejosa6779282023-02-08 00:50:04 +0100109 for (i = 1; i < 25; i++) {
110 s[i] = ROT64(s[i], rho[i-1]);
111 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200112
113 /* Pi */
114 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +0100115 for (i = 0; i < 24; i++) {
116 SWAP(s[pi[i]], t);
117 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200118
119 /* Chi */
120 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
121 s[0] ^= (~lane[1]) & lane[2];
122 s[1] ^= (~lane[2]) & lane[3];
123 s[2] ^= (~lane[3]) & lane[4];
124 s[3] ^= (~lane[4]) & lane[0];
125 s[4] ^= (~lane[0]) & lane[1];
126
127 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
128 s[5] ^= (~lane[1]) & lane[2];
129 s[6] ^= (~lane[2]) & lane[3];
130 s[7] ^= (~lane[3]) & lane[4];
131 s[8] ^= (~lane[4]) & lane[0];
132 s[9] ^= (~lane[0]) & lane[1];
133
134 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
135 s[10] ^= (~lane[1]) & lane[2];
136 s[11] ^= (~lane[2]) & lane[3];
137 s[12] ^= (~lane[3]) & lane[4];
138 s[13] ^= (~lane[4]) & lane[0];
139 s[14] ^= (~lane[0]) & lane[1];
140
141 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
142 s[15] ^= (~lane[1]) & lane[2];
143 s[16] ^= (~lane[2]) & lane[3];
144 s[17] ^= (~lane[3]) & lane[4];
145 s[18] ^= (~lane[4]) & lane[0];
146 s[19] ^= (~lane[0]) & lane[1];
147
148 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
149 s[20] ^= (~lane[1]) & lane[2];
150 s[21] ^= (~lane[2]) & lane[3];
151 s[22] ^= (~lane[3]) & lane[4];
152 s[23] ^= (~lane[4]) & lane[0];
153 s[24] ^= (~lane[0]) & lane[1];
154
155 /* Iota */
156 s[0] ^= rc[round];
157 }
158}
159
Pol Henarejosa6779282023-02-08 00:50:04 +0100160void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200161{
Pol Henarejosa6779282023-02-08 00:50:04 +0100162 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200163 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100164 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200165
Pol Henarejosa6779282023-02-08 00:50:04 +0100166 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200167}
168
Pol Henarejosa6779282023-02-08 00:50:04 +0100169void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200170{
Pol Henarejosa6779282023-02-08 00:50:04 +0100171 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200172 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100173 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200174
Pol Henarejosa6779282023-02-08 00:50:04 +0100175 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200176}
177
Pol Henarejosa6779282023-02-08 00:50:04 +0100178void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
179 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200180{
Pol Henarejosa6779282023-02-08 00:50:04 +0100181 if (dst == NULL || src == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200182 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100183 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200184
185 *dst = *src;
186}
187
188/*
189 * SHA-3 context setup
190 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100191int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200192{
193 mbedtls_sha3_family_functions *p = NULL;
Pol Henarejosa6779282023-02-08 00:50:04 +0100194 if (ctx == NULL) {
195 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200196 }
197
Pol Henarejosa6779282023-02-08 00:50:04 +0100198 for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
199 if (p->id == id) {
200 break;
201 }
202 }
203
204 if (p == NULL || p->id == MBEDTLS_SHA3_NONE) {
205 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
206 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200207
208 ctx->id = id;
209 ctx->r = p->r;
210 ctx->olen = p->olen / 8;
211 ctx->xor_byte = p->xor_byte;
212 ctx->max_block_size = ctx->r / 8;
213
Pol Henarejosa6779282023-02-08 00:50:04 +0100214 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200215 ctx->index = 0;
216
Pol Henarejosa6779282023-02-08 00:50:04 +0100217 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200218}
219
220/*
221 * SHA-3 process buffer
222 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100223int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
224 const uint8_t *input,
225 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200226{
Pol Henarejosa6779282023-02-08 00:50:04 +0100227 if (ctx == NULL) {
228 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200229 }
230
Pol Henarejosa6779282023-02-08 00:50:04 +0100231 if (ilen == 0 || input == NULL) {
232 return 0;
233 }
234
235 while (ilen-- > 0) {
236 ABSORB(ctx, ctx->index, *input++);
237 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
238 keccak_f1600(ctx);
239 }
240 }
241
242 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200243}
244
Pol Henarejosa6779282023-02-08 00:50:04 +0100245int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
246 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200247{
Pol Henarejosa6779282023-02-08 00:50:04 +0100248 if (ctx == NULL || output == NULL) {
249 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
250 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200251
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200252 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100253 if (ctx->olen > 0) {
254 if (ctx->olen > olen) {
255 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
256 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200257 olen = ctx->olen;
258 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200259
Pol Henarejosa6779282023-02-08 00:50:04 +0100260 ABSORB(ctx, ctx->index, ctx->xor_byte);
261 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
262 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200263 ctx->index = 0;
264
Pol Henarejosa6779282023-02-08 00:50:04 +0100265 while (olen-- > 0) {
266 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200267
Pol Henarejosa6779282023-02-08 00:50:04 +0100268 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
269 keccak_f1600(ctx);
270 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200271 }
272
Pol Henarejosa6779282023-02-08 00:50:04 +0100273 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200274}
275
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200276/*
277 * output = SHA3( input buffer )
278 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100279int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
280 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281{
282 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
283 mbedtls_sha3_context ctx;
284
Pol Henarejosa6779282023-02-08 00:50:04 +0100285 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286
Pol Henarejos85eeda02022-05-17 11:43:15 +0200287 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100288 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200289 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100290 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200291
Pol Henarejosa6779282023-02-08 00:50:04 +0100292 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200293 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100294 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200295
Pol Henarejosa6779282023-02-08 00:50:04 +0100296 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200297 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100298 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200299
300exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100301 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200302
Pol Henarejosa6779282023-02-08 00:50:04 +0100303 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200304}
305
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200306/**************** Self-tests ****************/
307
308#if defined(MBEDTLS_SELF_TEST)
309
310static const unsigned char test_data[2][4] =
311{
312 "",
313 "abc",
314};
315
316static const size_t test_data_len[2] =
317{
318 0, /* "" */
319 3 /* "abc" */
320};
321
322static const unsigned char test_hash_sha3_224[2][28] =
323{
324 { /* "" */
325 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
326 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
327 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
328 0x5B, 0x5A, 0x6B, 0xC7
329 },
330 { /* "abc" */
331 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
332 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
333 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
334 0x73, 0xB4, 0x6F, 0xDF
335 }
336};
337
338static const unsigned char test_hash_sha3_256[2][32] =
339{
340 { /* "" */
341 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
342 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
343 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
344 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
345 },
346 { /* "abc" */
347 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
348 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
349 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
350 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
351 }
352};
353
354static const unsigned char test_hash_sha3_384[2][48] =
355{
356 { /* "" */
357 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
358 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
359 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
360 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
361 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
362 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
363 },
364 { /* "abc" */
365 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
366 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
367 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
368 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
369 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
370 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
371 }
372};
373
374static const unsigned char test_hash_sha3_512[2][64] =
375{
376 { /* "" */
377 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
378 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
379 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
380 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
381 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
382 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
383 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
384 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
385 },
386 { /* "abc" */
387 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
388 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
389 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
390 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
391 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
392 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
393 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
394 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
395 }
396};
397
398static const unsigned char long_kat_hash_sha3_224[28] =
399{
400 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
401 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
402 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
403 0xA7, 0xFD, 0x65, 0x3C
404};
405
406static const unsigned char long_kat_hash_sha3_256[32] =
407{
408 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
409 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
410 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
411 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
412};
413
414static const unsigned char long_kat_hash_sha3_384[48] =
415{
416 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
417 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
418 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
419 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
420 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
421 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
422};
423
424static const unsigned char long_kat_hash_sha3_512[64] =
425{
426 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
427 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
428 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
429 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
430 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
431 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
432 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
433 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
434};
435
Pol Henarejosa6779282023-02-08 00:50:04 +0100436static int mbedtls_sha3_kat_test(int verbose,
437 const char *type_name,
438 mbedtls_sha3_id id,
439 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200440{
441 uint8_t hash[64];
442 int result;
443
Pol Henarejosa6779282023-02-08 00:50:04 +0100444 result = mbedtls_sha3(id,
445 test_data[test_num], test_data_len[test_num],
446 hash, sizeof(hash));
447 if (result != 0) {
448 if (verbose != 0) {
449 mbedtls_printf(" %s test %d error code: %d\n",
450 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200451 }
452
Pol Henarejosa6779282023-02-08 00:50:04 +0100453 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200454 }
455
Pol Henarejosa6779282023-02-08 00:50:04 +0100456 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200457 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100458 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200459 break;
460 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100461 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200462 break;
463 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100464 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200465 break;
466 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100467 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200468 break;
469 default:
470 break;
471 }
472
Pol Henarejosa6779282023-02-08 00:50:04 +0100473 if (0 != result) {
474 if (verbose != 0) {
475 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200476 }
477
Pol Henarejosa6779282023-02-08 00:50:04 +0100478 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200479 }
480
Pol Henarejosa6779282023-02-08 00:50:04 +0100481 if (verbose != 0) {
482 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200483 }
484
Pol Henarejosa6779282023-02-08 00:50:04 +0100485 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200486}
487
Pol Henarejosa6779282023-02-08 00:50:04 +0100488static int mbedtls_sha3_long_kat_test(int verbose,
489 const char *type_name,
490 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200491{
492 mbedtls_sha3_context ctx;
493 unsigned char buffer[1000];
494 unsigned char hash[64];
495 int i;
496 int result = 0;
497
Pol Henarejosa6779282023-02-08 00:50:04 +0100498 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200499
Pol Henarejosa6779282023-02-08 00:50:04 +0100500 if (verbose != 0) {
501 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200502 }
503
Pol Henarejosa6779282023-02-08 00:50:04 +0100504 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200505
Pol Henarejosa6779282023-02-08 00:50:04 +0100506 result = mbedtls_sha3_starts(&ctx, id);
507 if (result != 0) {
508 if (verbose != 0) {
509 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200510 }
511 }
512
513 /* Process 1,000,000 (one million) 'a' characters */
Pol Henarejosa6779282023-02-08 00:50:04 +0100514 for (i = 0; i < 1000; i++) {
515 result = mbedtls_sha3_update(&ctx, buffer, 1000);
516 if (result != 0) {
517 if (verbose != 0) {
518 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200519 }
520
521 goto cleanup;
522 }
523 }
524
Pol Henarejosa6779282023-02-08 00:50:04 +0100525 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
526 if (result != 0) {
527 if (verbose != 0) {
528 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200529 }
530
531 goto cleanup;
532 }
533
Pol Henarejosa6779282023-02-08 00:50:04 +0100534 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200535 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100536 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200537 break;
538 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100539 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200540 break;
541 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100542 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200543 break;
544 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100545 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200546 break;
547 default:
548 break;
549 }
550
Pol Henarejosa6779282023-02-08 00:50:04 +0100551 if (result != 0) {
552 if (verbose != 0) {
553 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200554 }
555 }
556
Pol Henarejosa6779282023-02-08 00:50:04 +0100557 if (verbose != 0) {
558 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200559 }
560
561cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100562 mbedtls_sha3_free(&ctx);
563 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200564}
565
Pol Henarejosa6779282023-02-08 00:50:04 +0100566int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200567{
568 int i;
569
570 /* SHA3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100571 for (i = 0; i < 2; i++) {
572 if (0 != mbedtls_sha3_kat_test(verbose,
573 "SHA3-224", MBEDTLS_SHA3_224, i)) {
574 return 1;
575 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200576
Pol Henarejosa6779282023-02-08 00:50:04 +0100577 if (0 != mbedtls_sha3_kat_test(verbose,
578 "SHA3-256", MBEDTLS_SHA3_256, i)) {
579 return 1;
580 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200581
Pol Henarejosa6779282023-02-08 00:50:04 +0100582 if (0 != mbedtls_sha3_kat_test(verbose,
583 "SHA3-384", MBEDTLS_SHA3_384, i)) {
584 return 1;
585 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200586
Pol Henarejosa6779282023-02-08 00:50:04 +0100587 if (0 != mbedtls_sha3_kat_test(verbose,
588 "SHA3-512", MBEDTLS_SHA3_512, i)) {
589 return 1;
590 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200591 }
592
593 /* SHA3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100594 if (0 != mbedtls_sha3_long_kat_test(verbose,
595 "SHA3-224", MBEDTLS_SHA3_224)) {
596 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200597 }
598
Pol Henarejosa6779282023-02-08 00:50:04 +0100599 if (0 != mbedtls_sha3_long_kat_test(verbose,
600 "SHA3-256", MBEDTLS_SHA3_256)) {
601 return 1;
602 }
603
604 if (0 != mbedtls_sha3_long_kat_test(verbose,
605 "SHA3-384", MBEDTLS_SHA3_384)) {
606 return 1;
607 }
608
609 if (0 != mbedtls_sha3_long_kat_test(verbose,
610 "SHA3-512", MBEDTLS_SHA3_512)) {
611 return 1;
612 }
613
614 if (verbose != 0) {
615 mbedtls_printf("\n");
616 }
617
618 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200619}
620#endif /* MBEDTLS_SELF_TEST */
621
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200622#endif /* MBEDTLS_SHA3_C */