blob: 93c5b7e681646f53f68c6bca8a5c4c1ad723960d [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
38static const uint8_t rho[24] = {
Dave Rodgman255a0f52024-02-13 17:55:18 +000039 63, 2, 36, 37, 28, 20, 58, 9, 44, 61, 54, 21, 39, 25, 23, 19, 49, 43, 56, 46, 62, 3, 8, 50
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 */
Pol Henarejosa6779282023-02-08 00:50:04 +010086 for (i = 1; i < 25; i++) {
Dave Rodgman255a0f52024-02-13 17:55:18 +000087 s[i] = ROTR64(s[i], rho[i-1]);
Pol Henarejosa6779282023-02-08 00:50:04 +010088 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020089
90 /* Pi */
91 t = s[1];
Pol Henarejosa6779282023-02-08 00:50:04 +010092 for (i = 0; i < 24; i++) {
93 SWAP(s[pi[i]], t);
94 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020095
96 /* Chi */
97 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
98 s[0] ^= (~lane[1]) & lane[2];
99 s[1] ^= (~lane[2]) & lane[3];
100 s[2] ^= (~lane[3]) & lane[4];
101 s[3] ^= (~lane[4]) & lane[0];
102 s[4] ^= (~lane[0]) & lane[1];
103
104 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
105 s[5] ^= (~lane[1]) & lane[2];
106 s[6] ^= (~lane[2]) & lane[3];
107 s[7] ^= (~lane[3]) & lane[4];
108 s[8] ^= (~lane[4]) & lane[0];
109 s[9] ^= (~lane[0]) & lane[1];
110
111 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
112 s[10] ^= (~lane[1]) & lane[2];
113 s[11] ^= (~lane[2]) & lane[3];
114 s[12] ^= (~lane[3]) & lane[4];
115 s[13] ^= (~lane[4]) & lane[0];
116 s[14] ^= (~lane[0]) & lane[1];
117
118 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
119 s[15] ^= (~lane[1]) & lane[2];
120 s[16] ^= (~lane[2]) & lane[3];
121 s[17] ^= (~lane[3]) & lane[4];
122 s[18] ^= (~lane[4]) & lane[0];
123 s[19] ^= (~lane[0]) & lane[1];
124
125 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
126 s[20] ^= (~lane[1]) & lane[2];
127 s[21] ^= (~lane[2]) & lane[3];
128 s[22] ^= (~lane[3]) & lane[4];
129 s[23] ^= (~lane[4]) & lane[0];
130 s[24] ^= (~lane[0]) & lane[1];
131
132 /* Iota */
133 s[0] ^= rc[round];
134 }
135}
136
Pol Henarejosa6779282023-02-08 00:50:04 +0100137void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200138{
Pol Henarejosa6779282023-02-08 00:50:04 +0100139 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200140}
141
Pol Henarejosa6779282023-02-08 00:50:04 +0100142void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200143{
Pol Henarejosa6779282023-02-08 00:50:04 +0100144 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200145 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100146 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200147
Pol Henarejosa6779282023-02-08 00:50:04 +0100148 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200149}
150
Pol Henarejosa6779282023-02-08 00:50:04 +0100151void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
152 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200153{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200154 *dst = *src;
155}
156
157/*
158 * SHA-3 context setup
159 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100160int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200161{
Gilles Peskinea3172d12024-02-08 10:47:08 +0100162 switch (id) {
163 case MBEDTLS_SHA3_224:
164 ctx->olen = 224 / 8;
165 ctx->max_block_size = 1152 / 8;
Pol Henarejosa6779282023-02-08 00:50:04 +0100166 break;
Gilles Peskinea3172d12024-02-08 10:47:08 +0100167 case MBEDTLS_SHA3_256:
168 ctx->olen = 256 / 8;
169 ctx->max_block_size = 1088 / 8;
170 break;
171 case MBEDTLS_SHA3_384:
172 ctx->olen = 384 / 8;
173 ctx->max_block_size = 832 / 8;
174 break;
175 case MBEDTLS_SHA3_512:
176 ctx->olen = 512 / 8;
177 ctx->max_block_size = 576 / 8;
178 break;
179 default:
180 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejosa6779282023-02-08 00:50:04 +0100181 }
182
Pol Henarejosa6779282023-02-08 00:50:04 +0100183 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200184 ctx->index = 0;
185
Pol Henarejosa6779282023-02-08 00:50:04 +0100186 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200187}
188
189/*
190 * SHA-3 process buffer
191 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100192int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
193 const uint8_t *input,
194 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200195{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100196 if (ilen >= 8) {
197 // 8-byte align index
198 int align_bytes = 8 - (ctx->index % 8);
199 if (align_bytes) {
200 for (; align_bytes > 0; align_bytes--) {
201 ABSORB(ctx, ctx->index, *input++);
202 ilen--;
203 ctx->index++;
204 }
205 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
206 keccak_f1600(ctx);
207 }
208 }
209
210 // process input in 8-byte chunks
211 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100212 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100213 input += 8;
214 ilen -= 8;
215 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
216 keccak_f1600(ctx);
217 }
218 }
219 }
220
221 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100222 while (ilen-- > 0) {
223 ABSORB(ctx, ctx->index, *input++);
224 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
225 keccak_f1600(ctx);
226 }
227 }
228
229 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200230}
231
Pol Henarejosa6779282023-02-08 00:50:04 +0100232int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
233 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200234{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100235 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
236
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200237 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100238 if (ctx->olen > 0) {
239 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100240 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
241 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100242 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200243 olen = ctx->olen;
244 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200245
Dave Rodgman1789d842023-05-29 22:05:19 +0100246 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100247 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
248 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200249 ctx->index = 0;
250
Pol Henarejosa6779282023-02-08 00:50:04 +0100251 while (olen-- > 0) {
252 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200253
Pol Henarejosa6779282023-02-08 00:50:04 +0100254 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
255 keccak_f1600(ctx);
256 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200257 }
258
Dave Rodgmandbddb002023-08-30 18:43:23 +0100259 ret = 0;
260
261exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100262 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100263 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200264}
265
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200266/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100267 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200268 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100269int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
270 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200271{
272 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
273 mbedtls_sha3_context ctx;
274
Pol Henarejosa6779282023-02-08 00:50:04 +0100275 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200276
Pol Henarejos85eeda02022-05-17 11:43:15 +0200277 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100278 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200279 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100280 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200281
Pol Henarejosa6779282023-02-08 00:50:04 +0100282 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200283 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100284 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200285
Pol Henarejosa6779282023-02-08 00:50:04 +0100286 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200287 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100288 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200289
290exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100291 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200292
Pol Henarejosa6779282023-02-08 00:50:04 +0100293 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200294}
295
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200296/**************** Self-tests ****************/
297
298#if defined(MBEDTLS_SELF_TEST)
299
300static const unsigned char test_data[2][4] =
301{
302 "",
303 "abc",
304};
305
306static const size_t test_data_len[2] =
307{
308 0, /* "" */
309 3 /* "abc" */
310};
311
312static const unsigned char test_hash_sha3_224[2][28] =
313{
314 { /* "" */
315 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
316 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
317 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
318 0x5B, 0x5A, 0x6B, 0xC7
319 },
320 { /* "abc" */
321 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
322 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
323 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
324 0x73, 0xB4, 0x6F, 0xDF
325 }
326};
327
328static const unsigned char test_hash_sha3_256[2][32] =
329{
330 { /* "" */
331 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
332 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
333 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
334 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
335 },
336 { /* "abc" */
337 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
338 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
339 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
340 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
341 }
342};
343
344static const unsigned char test_hash_sha3_384[2][48] =
345{
346 { /* "" */
347 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
348 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
349 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
350 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
351 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
352 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
353 },
354 { /* "abc" */
355 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
356 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
357 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
358 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
359 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
360 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
361 }
362};
363
364static const unsigned char test_hash_sha3_512[2][64] =
365{
366 { /* "" */
367 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
368 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
369 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
370 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
371 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
372 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
373 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
374 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
375 },
376 { /* "abc" */
377 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
378 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
379 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
380 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
381 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
382 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
383 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
384 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
385 }
386};
387
388static const unsigned char long_kat_hash_sha3_224[28] =
389{
390 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
391 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
392 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
393 0xA7, 0xFD, 0x65, 0x3C
394};
395
396static const unsigned char long_kat_hash_sha3_256[32] =
397{
398 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
399 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
400 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
401 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
402};
403
404static const unsigned char long_kat_hash_sha3_384[48] =
405{
406 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
407 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
408 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
409 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
410 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
411 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
412};
413
414static const unsigned char long_kat_hash_sha3_512[64] =
415{
416 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
417 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
418 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
419 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
420 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
421 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
422 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
423 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
424};
425
Pol Henarejosa6779282023-02-08 00:50:04 +0100426static int mbedtls_sha3_kat_test(int verbose,
427 const char *type_name,
428 mbedtls_sha3_id id,
429 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200430{
431 uint8_t hash[64];
432 int result;
433
Pol Henarejosa6779282023-02-08 00:50:04 +0100434 result = mbedtls_sha3(id,
435 test_data[test_num], test_data_len[test_num],
436 hash, sizeof(hash));
437 if (result != 0) {
438 if (verbose != 0) {
439 mbedtls_printf(" %s test %d error code: %d\n",
440 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200441 }
442
Pol Henarejosa6779282023-02-08 00:50:04 +0100443 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200444 }
445
Pol Henarejosa6779282023-02-08 00:50:04 +0100446 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200447 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100448 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200449 break;
450 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100451 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200452 break;
453 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100454 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200455 break;
456 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100457 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200458 break;
459 default:
460 break;
461 }
462
Pol Henarejosa6779282023-02-08 00:50:04 +0100463 if (0 != result) {
464 if (verbose != 0) {
465 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200466 }
467
Pol Henarejosa6779282023-02-08 00:50:04 +0100468 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200469 }
470
Pol Henarejosa6779282023-02-08 00:50:04 +0100471 if (verbose != 0) {
472 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200473 }
474
Pol Henarejosa6779282023-02-08 00:50:04 +0100475 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200476}
477
Pol Henarejosa6779282023-02-08 00:50:04 +0100478static int mbedtls_sha3_long_kat_test(int verbose,
479 const char *type_name,
480 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200481{
482 mbedtls_sha3_context ctx;
483 unsigned char buffer[1000];
484 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200485 int result = 0;
486
Pol Henarejosa6779282023-02-08 00:50:04 +0100487 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200488
Pol Henarejosa6779282023-02-08 00:50:04 +0100489 if (verbose != 0) {
490 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200491 }
492
Pol Henarejosa6779282023-02-08 00:50:04 +0100493 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200494
Pol Henarejosa6779282023-02-08 00:50:04 +0100495 result = mbedtls_sha3_starts(&ctx, id);
496 if (result != 0) {
497 if (verbose != 0) {
498 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200499 }
500 }
501
502 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100503 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100504 result = mbedtls_sha3_update(&ctx, buffer, 1000);
505 if (result != 0) {
506 if (verbose != 0) {
507 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200508 }
509
510 goto cleanup;
511 }
512 }
513
Pol Henarejosa6779282023-02-08 00:50:04 +0100514 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
515 if (result != 0) {
516 if (verbose != 0) {
517 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200518 }
519
520 goto cleanup;
521 }
522
Pol Henarejosa6779282023-02-08 00:50:04 +0100523 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200524 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100525 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200526 break;
527 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100528 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200529 break;
530 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100531 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200532 break;
533 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100534 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200535 break;
536 default:
537 break;
538 }
539
Pol Henarejosa6779282023-02-08 00:50:04 +0100540 if (result != 0) {
541 if (verbose != 0) {
542 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200543 }
544 }
545
Pol Henarejosa6779282023-02-08 00:50:04 +0100546 if (verbose != 0) {
547 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200548 }
549
550cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100551 mbedtls_sha3_free(&ctx);
552 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200553}
554
Pol Henarejosa6779282023-02-08 00:50:04 +0100555int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200556{
557 int i;
558
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100559 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100560 for (i = 0; i < 2; i++) {
561 if (0 != mbedtls_sha3_kat_test(verbose,
562 "SHA3-224", MBEDTLS_SHA3_224, i)) {
563 return 1;
564 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200565
Pol Henarejosa6779282023-02-08 00:50:04 +0100566 if (0 != mbedtls_sha3_kat_test(verbose,
567 "SHA3-256", MBEDTLS_SHA3_256, 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-384", MBEDTLS_SHA3_384, 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-512", MBEDTLS_SHA3_512, i)) {
578 return 1;
579 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200580 }
581
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100582 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100583 if (0 != mbedtls_sha3_long_kat_test(verbose,
584 "SHA3-224", MBEDTLS_SHA3_224)) {
585 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200586 }
587
Pol Henarejosa6779282023-02-08 00:50:04 +0100588 if (0 != mbedtls_sha3_long_kat_test(verbose,
589 "SHA3-256", MBEDTLS_SHA3_256)) {
590 return 1;
591 }
592
593 if (0 != mbedtls_sha3_long_kat_test(verbose,
594 "SHA3-384", MBEDTLS_SHA3_384)) {
595 return 1;
596 }
597
598 if (0 != mbedtls_sha3_long_kat_test(verbose,
599 "SHA3-512", MBEDTLS_SHA3_512)) {
600 return 1;
601 }
602
603 if (verbose != 0) {
604 mbedtls_printf("\n");
605 }
606
607 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200608}
609#endif /* MBEDTLS_SELF_TEST */
610
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200611#endif /* MBEDTLS_SHA3_C */