blob: 4c1a1a9d4d74fa6c939601b8d3ff566aaa4027a1 [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
Tom Cosgrove876346e2023-09-09 14:24:46 +0100203 if (p->id == MBEDTLS_SHA3_NONE) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100204 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 Rodgman2c91f4b2023-06-07 19:59:05 +0100239 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
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{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100262 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
263
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200264 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100265 if (ctx->olen > 0) {
266 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100267 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
268 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100269 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200270 olen = ctx->olen;
271 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200272
Dave Rodgman1789d842023-05-29 22:05:19 +0100273 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100274 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
275 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200276 ctx->index = 0;
277
Pol Henarejosa6779282023-02-08 00:50:04 +0100278 while (olen-- > 0) {
279 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200280
Pol Henarejosa6779282023-02-08 00:50:04 +0100281 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
282 keccak_f1600(ctx);
283 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200284 }
285
Dave Rodgmandbddb002023-08-30 18:43:23 +0100286 ret = 0;
287
288exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100289 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100290 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200291}
292
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200293/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100294 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200295 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100296int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
297 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200298{
299 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
300 mbedtls_sha3_context ctx;
301
Pol Henarejosa6779282023-02-08 00:50:04 +0100302 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200303
Pol Henarejos85eeda02022-05-17 11:43:15 +0200304 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100305 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200306 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100307 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200308
Pol Henarejosa6779282023-02-08 00:50:04 +0100309 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200310 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100311 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200312
Pol Henarejosa6779282023-02-08 00:50:04 +0100313 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200314 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100315 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200316
317exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100318 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200319
Pol Henarejosa6779282023-02-08 00:50:04 +0100320 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200321}
322
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200323/**************** Self-tests ****************/
324
325#if defined(MBEDTLS_SELF_TEST)
326
327static const unsigned char test_data[2][4] =
328{
329 "",
330 "abc",
331};
332
333static const size_t test_data_len[2] =
334{
335 0, /* "" */
336 3 /* "abc" */
337};
338
339static const unsigned char test_hash_sha3_224[2][28] =
340{
341 { /* "" */
342 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
343 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
344 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
345 0x5B, 0x5A, 0x6B, 0xC7
346 },
347 { /* "abc" */
348 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
349 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
350 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
351 0x73, 0xB4, 0x6F, 0xDF
352 }
353};
354
355static const unsigned char test_hash_sha3_256[2][32] =
356{
357 { /* "" */
358 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
359 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
360 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
361 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
362 },
363 { /* "abc" */
364 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
365 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
366 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
367 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
368 }
369};
370
371static const unsigned char test_hash_sha3_384[2][48] =
372{
373 { /* "" */
374 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
375 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
376 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
377 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
378 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
379 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
380 },
381 { /* "abc" */
382 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
383 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
384 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
385 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
386 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
387 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
388 }
389};
390
391static const unsigned char test_hash_sha3_512[2][64] =
392{
393 { /* "" */
394 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
395 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
396 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
397 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
398 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
399 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
400 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
401 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
402 },
403 { /* "abc" */
404 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
405 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
406 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
407 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
408 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
409 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
410 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
411 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
412 }
413};
414
415static const unsigned char long_kat_hash_sha3_224[28] =
416{
417 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
418 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
419 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
420 0xA7, 0xFD, 0x65, 0x3C
421};
422
423static const unsigned char long_kat_hash_sha3_256[32] =
424{
425 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
426 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
427 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
428 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
429};
430
431static const unsigned char long_kat_hash_sha3_384[48] =
432{
433 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
434 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
435 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
436 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
437 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
438 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
439};
440
441static const unsigned char long_kat_hash_sha3_512[64] =
442{
443 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
444 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
445 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
446 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
447 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
448 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
449 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
450 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
451};
452
Pol Henarejosa6779282023-02-08 00:50:04 +0100453static int mbedtls_sha3_kat_test(int verbose,
454 const char *type_name,
455 mbedtls_sha3_id id,
456 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200457{
458 uint8_t hash[64];
459 int result;
460
Pol Henarejosa6779282023-02-08 00:50:04 +0100461 result = mbedtls_sha3(id,
462 test_data[test_num], test_data_len[test_num],
463 hash, sizeof(hash));
464 if (result != 0) {
465 if (verbose != 0) {
466 mbedtls_printf(" %s test %d error code: %d\n",
467 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200468 }
469
Pol Henarejosa6779282023-02-08 00:50:04 +0100470 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200471 }
472
Pol Henarejosa6779282023-02-08 00:50:04 +0100473 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200474 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100475 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200476 break;
477 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100478 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200479 break;
480 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100481 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200482 break;
483 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100484 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200485 break;
486 default:
487 break;
488 }
489
Pol Henarejosa6779282023-02-08 00:50:04 +0100490 if (0 != result) {
491 if (verbose != 0) {
492 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200493 }
494
Pol Henarejosa6779282023-02-08 00:50:04 +0100495 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200496 }
497
Pol Henarejosa6779282023-02-08 00:50:04 +0100498 if (verbose != 0) {
499 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200500 }
501
Pol Henarejosa6779282023-02-08 00:50:04 +0100502 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503}
504
Pol Henarejosa6779282023-02-08 00:50:04 +0100505static int mbedtls_sha3_long_kat_test(int verbose,
506 const char *type_name,
507 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200508{
509 mbedtls_sha3_context ctx;
510 unsigned char buffer[1000];
511 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200512 int result = 0;
513
Pol Henarejosa6779282023-02-08 00:50:04 +0100514 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200515
Pol Henarejosa6779282023-02-08 00:50:04 +0100516 if (verbose != 0) {
517 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200518 }
519
Pol Henarejosa6779282023-02-08 00:50:04 +0100520 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200521
Pol Henarejosa6779282023-02-08 00:50:04 +0100522 result = mbedtls_sha3_starts(&ctx, id);
523 if (result != 0) {
524 if (verbose != 0) {
525 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200526 }
527 }
528
529 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100530 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100531 result = mbedtls_sha3_update(&ctx, buffer, 1000);
532 if (result != 0) {
533 if (verbose != 0) {
534 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200535 }
536
537 goto cleanup;
538 }
539 }
540
Pol Henarejosa6779282023-02-08 00:50:04 +0100541 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
542 if (result != 0) {
543 if (verbose != 0) {
544 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200545 }
546
547 goto cleanup;
548 }
549
Pol Henarejosa6779282023-02-08 00:50:04 +0100550 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200551 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100552 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200553 break;
554 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100555 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200556 break;
557 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100558 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200559 break;
560 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100561 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200562 break;
563 default:
564 break;
565 }
566
Pol Henarejosa6779282023-02-08 00:50:04 +0100567 if (result != 0) {
568 if (verbose != 0) {
569 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200570 }
571 }
572
Pol Henarejosa6779282023-02-08 00:50:04 +0100573 if (verbose != 0) {
574 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200575 }
576
577cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100578 mbedtls_sha3_free(&ctx);
579 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200580}
581
Pol Henarejosa6779282023-02-08 00:50:04 +0100582int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200583{
584 int i;
585
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100586 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100587 for (i = 0; i < 2; i++) {
588 if (0 != mbedtls_sha3_kat_test(verbose,
589 "SHA3-224", MBEDTLS_SHA3_224, i)) {
590 return 1;
591 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200592
Pol Henarejosa6779282023-02-08 00:50:04 +0100593 if (0 != mbedtls_sha3_kat_test(verbose,
594 "SHA3-256", MBEDTLS_SHA3_256, i)) {
595 return 1;
596 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200597
Pol Henarejosa6779282023-02-08 00:50:04 +0100598 if (0 != mbedtls_sha3_kat_test(verbose,
599 "SHA3-384", MBEDTLS_SHA3_384, i)) {
600 return 1;
601 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200602
Pol Henarejosa6779282023-02-08 00:50:04 +0100603 if (0 != mbedtls_sha3_kat_test(verbose,
604 "SHA3-512", MBEDTLS_SHA3_512, i)) {
605 return 1;
606 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200607 }
608
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100609 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100610 if (0 != mbedtls_sha3_long_kat_test(verbose,
611 "SHA3-224", MBEDTLS_SHA3_224)) {
612 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200613 }
614
Pol Henarejosa6779282023-02-08 00:50:04 +0100615 if (0 != mbedtls_sha3_long_kat_test(verbose,
616 "SHA3-256", MBEDTLS_SHA3_256)) {
617 return 1;
618 }
619
620 if (0 != mbedtls_sha3_long_kat_test(verbose,
621 "SHA3-384", MBEDTLS_SHA3_384)) {
622 return 1;
623 }
624
625 if (0 != mbedtls_sha3_long_kat_test(verbose,
626 "SHA3-512", MBEDTLS_SHA3_512)) {
627 return 1;
628 }
629
630 if (verbose != 0) {
631 mbedtls_printf("\n");
632 }
633
634 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200635}
636#endif /* MBEDTLS_SELF_TEST */
637
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200638#endif /* MBEDTLS_SHA3_C */