blob: 29908fb342a6f4755576c85b87e4ca24638a9276 [file] [log] [blame]
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +02001/*
2 * FIPS-202 compliant SHA3 implementation
3 *
4 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +02006 */
7/*
8 * The SHA-3 Secure Hash Standard was published by NIST in 2015.
9 *
10 * https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
11 */
12
13#include "common.h"
14
15#if defined(MBEDTLS_SHA3_C)
16
17#include "mbedtls/sha3.h"
18#include "mbedtls/platform_util.h"
19#include "mbedtls/error.h"
20
21#include <string.h>
22
23#if defined(MBEDTLS_SELF_TEST)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020024#include "mbedtls/platform.h"
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020025#endif /* MBEDTLS_SELF_TEST */
26
Dave Rodgman1789d842023-05-29 22:05:19 +010027#define XOR_BYTE 0x6
28
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020029static const uint64_t rc[24] = {
30 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
31 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
32 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
33 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
34 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
35 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
36};
37
Dave Rodgmand407e0d2024-02-13 18:27:55 +000038static const uint32_t rho[6] = {
39 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020040};
41
42static const uint8_t pi[24] = {
43 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
44 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
45};
46
Dave Rodgman255a0f52024-02-13 17:55:18 +000047#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
Pol Henarejosa6779282023-02-08 00:50:04 +010048#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
49} while (0)
50#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
51#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020052
53/* The permutation function. */
54static void keccak_f1600(mbedtls_sha3_context *ctx)
55{
56 uint64_t lane[5];
57 uint64_t *s = ctx->state;
58 int i;
59
Pol Henarejosa6779282023-02-08 00:50:04 +010060 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020061 uint64_t t;
62
63 /* Theta */
64 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
65 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
66 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
67 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
68 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
69
Dave Rodgman255a0f52024-02-13 17:55:18 +000070 t = lane[4] ^ ROTR64(lane[1], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020071 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
72
Dave Rodgman255a0f52024-02-13 17:55:18 +000073 t = lane[0] ^ ROTR64(lane[2], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020074 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
75
Dave Rodgman255a0f52024-02-13 17:55:18 +000076 t = lane[1] ^ ROTR64(lane[3], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020077 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
78
Dave Rodgman255a0f52024-02-13 17:55:18 +000079 t = lane[2] ^ ROTR64(lane[4], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020080 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
81
Dave Rodgman255a0f52024-02-13 17:55:18 +000082 t = lane[3] ^ ROTR64(lane[0], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020083 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
84
85 /* Rho */
Dave Rodgmand407e0d2024-02-13 18:27:55 +000086 for (i = 1; i < 25; i += 4) {
87 uint32_t r = rho[(i - 1) >> 2];
88 for (int j = i; j < i + 4; j++) {
89 uint8_t r8 = r >> 24;
90 r <<= 8;
91 s[j] = ROTR64(s[j], r8);
92 }
Pol Henarejosa6779282023-02-08 00:50:04 +010093 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020094
95 /* Pi */
96 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +010097 for (i = 0; i < 24; i++) {
98 SWAP(s[pi[i]], t);
99 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200100
101 /* Chi */
102 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
103 s[0] ^= (~lane[1]) & lane[2];
104 s[1] ^= (~lane[2]) & lane[3];
105 s[2] ^= (~lane[3]) & lane[4];
106 s[3] ^= (~lane[4]) & lane[0];
107 s[4] ^= (~lane[0]) & lane[1];
108
109 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
110 s[5] ^= (~lane[1]) & lane[2];
111 s[6] ^= (~lane[2]) & lane[3];
112 s[7] ^= (~lane[3]) & lane[4];
113 s[8] ^= (~lane[4]) & lane[0];
114 s[9] ^= (~lane[0]) & lane[1];
115
116 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
117 s[10] ^= (~lane[1]) & lane[2];
118 s[11] ^= (~lane[2]) & lane[3];
119 s[12] ^= (~lane[3]) & lane[4];
120 s[13] ^= (~lane[4]) & lane[0];
121 s[14] ^= (~lane[0]) & lane[1];
122
123 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
124 s[15] ^= (~lane[1]) & lane[2];
125 s[16] ^= (~lane[2]) & lane[3];
126 s[17] ^= (~lane[3]) & lane[4];
127 s[18] ^= (~lane[4]) & lane[0];
128 s[19] ^= (~lane[0]) & lane[1];
129
130 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
131 s[20] ^= (~lane[1]) & lane[2];
132 s[21] ^= (~lane[2]) & lane[3];
133 s[22] ^= (~lane[3]) & lane[4];
134 s[23] ^= (~lane[4]) & lane[0];
135 s[24] ^= (~lane[0]) & lane[1];
136
137 /* Iota */
138 s[0] ^= rc[round];
139 }
140}
141
Pol Henarejosa6779282023-02-08 00:50:04 +0100142void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200143{
Pol Henarejosa6779282023-02-08 00:50:04 +0100144 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200145}
146
Pol Henarejosa6779282023-02-08 00:50:04 +0100147void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200148{
Pol Henarejosa6779282023-02-08 00:50:04 +0100149 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200150 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100151 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200152
Pol Henarejosa6779282023-02-08 00:50:04 +0100153 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200154}
155
Pol Henarejosa6779282023-02-08 00:50:04 +0100156void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
157 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200158{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200159 *dst = *src;
160}
161
162/*
163 * SHA-3 context setup
164 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100165int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200166{
Gilles Peskinea3172d12024-02-08 10:47:08 +0100167 switch (id) {
168 case MBEDTLS_SHA3_224:
169 ctx->olen = 224 / 8;
170 ctx->max_block_size = 1152 / 8;
Pol Henarejosa6779282023-02-08 00:50:04 +0100171 break;
Gilles Peskinea3172d12024-02-08 10:47:08 +0100172 case MBEDTLS_SHA3_256:
173 ctx->olen = 256 / 8;
174 ctx->max_block_size = 1088 / 8;
175 break;
176 case MBEDTLS_SHA3_384:
177 ctx->olen = 384 / 8;
178 ctx->max_block_size = 832 / 8;
179 break;
180 case MBEDTLS_SHA3_512:
181 ctx->olen = 512 / 8;
182 ctx->max_block_size = 576 / 8;
183 break;
184 default:
185 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejosa6779282023-02-08 00:50:04 +0100186 }
187
Pol Henarejosa6779282023-02-08 00:50:04 +0100188 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200189 ctx->index = 0;
190
Pol Henarejosa6779282023-02-08 00:50:04 +0100191 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200192}
193
194/*
195 * SHA-3 process buffer
196 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100197int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
198 const uint8_t *input,
199 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200200{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100201 if (ilen >= 8) {
202 // 8-byte align index
203 int align_bytes = 8 - (ctx->index % 8);
204 if (align_bytes) {
205 for (; align_bytes > 0; align_bytes--) {
206 ABSORB(ctx, ctx->index, *input++);
207 ilen--;
208 ctx->index++;
209 }
210 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
211 keccak_f1600(ctx);
212 }
213 }
214
215 // process input in 8-byte chunks
216 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100217 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100218 input += 8;
219 ilen -= 8;
220 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
221 keccak_f1600(ctx);
222 }
223 }
224 }
225
226 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100227 while (ilen-- > 0) {
228 ABSORB(ctx, ctx->index, *input++);
229 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
230 keccak_f1600(ctx);
231 }
232 }
233
234 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200235}
236
Pol Henarejosa6779282023-02-08 00:50:04 +0100237int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
238 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200239{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100240 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
241
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200242 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100243 if (ctx->olen > 0) {
244 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100245 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
246 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100247 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200248 olen = ctx->olen;
249 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200250
Dave Rodgman1789d842023-05-29 22:05:19 +0100251 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100252 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
253 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200254 ctx->index = 0;
255
Pol Henarejosa6779282023-02-08 00:50:04 +0100256 while (olen-- > 0) {
257 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200258
Pol Henarejosa6779282023-02-08 00:50:04 +0100259 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
260 keccak_f1600(ctx);
261 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200262 }
263
Dave Rodgmandbddb002023-08-30 18:43:23 +0100264 ret = 0;
265
266exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100267 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100268 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200269}
270
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200271/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100272 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200273 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100274int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
275 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200276{
277 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
278 mbedtls_sha3_context ctx;
279
Pol Henarejosa6779282023-02-08 00:50:04 +0100280 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281
Pol Henarejos85eeda02022-05-17 11:43:15 +0200282 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100283 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200284 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100285 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200286
Pol Henarejosa6779282023-02-08 00:50:04 +0100287 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200288 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100289 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200290
Pol Henarejosa6779282023-02-08 00:50:04 +0100291 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200292 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100293 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200294
295exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100296 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200297
Pol Henarejosa6779282023-02-08 00:50:04 +0100298 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200299}
300
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200301/**************** Self-tests ****************/
302
303#if defined(MBEDTLS_SELF_TEST)
304
305static const unsigned char test_data[2][4] =
306{
307 "",
308 "abc",
309};
310
311static const size_t test_data_len[2] =
312{
313 0, /* "" */
314 3 /* "abc" */
315};
316
317static const unsigned char test_hash_sha3_224[2][28] =
318{
319 { /* "" */
320 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
321 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
322 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
323 0x5B, 0x5A, 0x6B, 0xC7
324 },
325 { /* "abc" */
326 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
327 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
328 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
329 0x73, 0xB4, 0x6F, 0xDF
330 }
331};
332
333static const unsigned char test_hash_sha3_256[2][32] =
334{
335 { /* "" */
336 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
337 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
338 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
339 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
340 },
341 { /* "abc" */
342 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
343 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
344 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
345 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
346 }
347};
348
349static const unsigned char test_hash_sha3_384[2][48] =
350{
351 { /* "" */
352 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
353 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
354 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
355 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
356 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
357 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
358 },
359 { /* "abc" */
360 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
361 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
362 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
363 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
364 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
365 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
366 }
367};
368
369static const unsigned char test_hash_sha3_512[2][64] =
370{
371 { /* "" */
372 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
373 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
374 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
375 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
376 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
377 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
378 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
379 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
380 },
381 { /* "abc" */
382 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
383 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
384 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
385 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
386 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
387 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
388 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
389 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
390 }
391};
392
393static const unsigned char long_kat_hash_sha3_224[28] =
394{
395 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
396 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
397 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
398 0xA7, 0xFD, 0x65, 0x3C
399};
400
401static const unsigned char long_kat_hash_sha3_256[32] =
402{
403 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
404 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
405 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
406 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
407};
408
409static const unsigned char long_kat_hash_sha3_384[48] =
410{
411 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
412 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
413 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
414 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
415 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
416 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
417};
418
419static const unsigned char long_kat_hash_sha3_512[64] =
420{
421 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
422 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
423 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
424 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
425 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
426 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
427 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
428 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
429};
430
Pol Henarejosa6779282023-02-08 00:50:04 +0100431static int mbedtls_sha3_kat_test(int verbose,
432 const char *type_name,
433 mbedtls_sha3_id id,
434 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200435{
436 uint8_t hash[64];
437 int result;
438
Pol Henarejosa6779282023-02-08 00:50:04 +0100439 result = mbedtls_sha3(id,
440 test_data[test_num], test_data_len[test_num],
441 hash, sizeof(hash));
442 if (result != 0) {
443 if (verbose != 0) {
444 mbedtls_printf(" %s test %d error code: %d\n",
445 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200446 }
447
Pol Henarejosa6779282023-02-08 00:50:04 +0100448 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200449 }
450
Pol Henarejosa6779282023-02-08 00:50:04 +0100451 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200452 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100453 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200454 break;
455 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100456 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200457 break;
458 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100459 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200460 break;
461 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100462 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200463 break;
464 default:
465 break;
466 }
467
Pol Henarejosa6779282023-02-08 00:50:04 +0100468 if (0 != result) {
469 if (verbose != 0) {
470 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200471 }
472
Pol Henarejosa6779282023-02-08 00:50:04 +0100473 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200474 }
475
Pol Henarejosa6779282023-02-08 00:50:04 +0100476 if (verbose != 0) {
477 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200478 }
479
Pol Henarejosa6779282023-02-08 00:50:04 +0100480 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200481}
482
Pol Henarejosa6779282023-02-08 00:50:04 +0100483static int mbedtls_sha3_long_kat_test(int verbose,
484 const char *type_name,
485 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200486{
487 mbedtls_sha3_context ctx;
488 unsigned char buffer[1000];
489 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200490 int result = 0;
491
Pol Henarejosa6779282023-02-08 00:50:04 +0100492 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200493
Pol Henarejosa6779282023-02-08 00:50:04 +0100494 if (verbose != 0) {
495 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200496 }
497
Pol Henarejosa6779282023-02-08 00:50:04 +0100498 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200499
Pol Henarejosa6779282023-02-08 00:50:04 +0100500 result = mbedtls_sha3_starts(&ctx, id);
501 if (result != 0) {
502 if (verbose != 0) {
503 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200504 }
505 }
506
507 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100508 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100509 result = mbedtls_sha3_update(&ctx, buffer, 1000);
510 if (result != 0) {
511 if (verbose != 0) {
512 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200513 }
514
515 goto cleanup;
516 }
517 }
518
Pol Henarejosa6779282023-02-08 00:50:04 +0100519 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
520 if (result != 0) {
521 if (verbose != 0) {
522 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200523 }
524
525 goto cleanup;
526 }
527
Pol Henarejosa6779282023-02-08 00:50:04 +0100528 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200529 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100530 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200531 break;
532 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100533 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200534 break;
535 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100536 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200537 break;
538 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100539 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200540 break;
541 default:
542 break;
543 }
544
Pol Henarejosa6779282023-02-08 00:50:04 +0100545 if (result != 0) {
546 if (verbose != 0) {
547 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200548 }
549 }
550
Pol Henarejosa6779282023-02-08 00:50:04 +0100551 if (verbose != 0) {
552 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200553 }
554
555cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100556 mbedtls_sha3_free(&ctx);
557 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200558}
559
Pol Henarejosa6779282023-02-08 00:50:04 +0100560int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200561{
562 int i;
563
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100564 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100565 for (i = 0; i < 2; i++) {
566 if (0 != mbedtls_sha3_kat_test(verbose,
567 "SHA3-224", MBEDTLS_SHA3_224, i)) {
568 return 1;
569 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200570
Pol Henarejosa6779282023-02-08 00:50:04 +0100571 if (0 != mbedtls_sha3_kat_test(verbose,
572 "SHA3-256", MBEDTLS_SHA3_256, i)) {
573 return 1;
574 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200575
Pol Henarejosa6779282023-02-08 00:50:04 +0100576 if (0 != mbedtls_sha3_kat_test(verbose,
577 "SHA3-384", MBEDTLS_SHA3_384, i)) {
578 return 1;
579 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200580
Pol Henarejosa6779282023-02-08 00:50:04 +0100581 if (0 != mbedtls_sha3_kat_test(verbose,
582 "SHA3-512", MBEDTLS_SHA3_512, i)) {
583 return 1;
584 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200585 }
586
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100587 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100588 if (0 != mbedtls_sha3_long_kat_test(verbose,
589 "SHA3-224", MBEDTLS_SHA3_224)) {
590 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200591 }
592
Pol Henarejosa6779282023-02-08 00:50:04 +0100593 if (0 != mbedtls_sha3_long_kat_test(verbose,
594 "SHA3-256", MBEDTLS_SHA3_256)) {
595 return 1;
596 }
597
598 if (0 != mbedtls_sha3_long_kat_test(verbose,
599 "SHA3-384", MBEDTLS_SHA3_384)) {
600 return 1;
601 }
602
603 if (0 != mbedtls_sha3_long_kat_test(verbose,
604 "SHA3-512", MBEDTLS_SHA3_512)) {
605 return 1;
606 }
607
608 if (verbose != 0) {
609 mbedtls_printf("\n");
610 }
611
612 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200613}
614#endif /* MBEDTLS_SELF_TEST */
615
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200616#endif /* MBEDTLS_SHA3_C */