blob: 9b22cfa04caf2debe6949585a94e3a9fa4bd2e15 [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
Dave Rodgmancfb126f2024-02-13 18:35:41 +000042static const uint32_t pi[6] = {
43 0x0a070b11, 0x12030510, 0x08151804, 0x0f17130d, 0x0c02140e, 0x16090601
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020044};
45
Dave Rodgman255a0f52024-02-13 17:55:18 +000046#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
Pol Henarejosa6779282023-02-08 00:50:04 +010047#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
48} while (0)
49#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
50#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020051
52/* The permutation function. */
53static void keccak_f1600(mbedtls_sha3_context *ctx)
54{
55 uint64_t lane[5];
56 uint64_t *s = ctx->state;
57 int i;
58
Pol Henarejosa6779282023-02-08 00:50:04 +010059 for (int round = 0; round < 24; round++) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020060 uint64_t t;
61
62 /* Theta */
63 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
64 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
65 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
66 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
67 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
68
Dave Rodgman255a0f52024-02-13 17:55:18 +000069 t = lane[4] ^ ROTR64(lane[1], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020070 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
71
Dave Rodgman255a0f52024-02-13 17:55:18 +000072 t = lane[0] ^ ROTR64(lane[2], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020073 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
74
Dave Rodgman255a0f52024-02-13 17:55:18 +000075 t = lane[1] ^ ROTR64(lane[3], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020076 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
77
Dave Rodgman255a0f52024-02-13 17:55:18 +000078 t = lane[2] ^ ROTR64(lane[4], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020079 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
80
Dave Rodgman255a0f52024-02-13 17:55:18 +000081 t = lane[3] ^ ROTR64(lane[0], 63);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020082 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
83
84 /* Rho */
Dave Rodgmand407e0d2024-02-13 18:27:55 +000085 for (i = 1; i < 25; i += 4) {
86 uint32_t r = rho[(i - 1) >> 2];
87 for (int j = i; j < i + 4; j++) {
88 uint8_t r8 = r >> 24;
89 r <<= 8;
90 s[j] = ROTR64(s[j], r8);
91 }
Pol Henarejosa6779282023-02-08 00:50:04 +010092 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +020093
94 /* Pi */
95 t = s[1];
Dave Rodgmancfb126f2024-02-13 18:35:41 +000096 for (i = 0; i < 24; i += 4) {
97 uint32_t p = pi[i >> 2];
98 for (unsigned j = 0; j < 4; j++) {
99 uint8_t p8 = (uint8_t) (p >> 24);
100 p <<= 8;
101 SWAP(s[p8], t);
102 }
Pol Henarejosa6779282023-02-08 00:50:04 +0100103 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200104
105 /* Chi */
106 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
107 s[0] ^= (~lane[1]) & lane[2];
108 s[1] ^= (~lane[2]) & lane[3];
109 s[2] ^= (~lane[3]) & lane[4];
110 s[3] ^= (~lane[4]) & lane[0];
111 s[4] ^= (~lane[0]) & lane[1];
112
113 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
114 s[5] ^= (~lane[1]) & lane[2];
115 s[6] ^= (~lane[2]) & lane[3];
116 s[7] ^= (~lane[3]) & lane[4];
117 s[8] ^= (~lane[4]) & lane[0];
118 s[9] ^= (~lane[0]) & lane[1];
119
120 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
121 s[10] ^= (~lane[1]) & lane[2];
122 s[11] ^= (~lane[2]) & lane[3];
123 s[12] ^= (~lane[3]) & lane[4];
124 s[13] ^= (~lane[4]) & lane[0];
125 s[14] ^= (~lane[0]) & lane[1];
126
127 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
128 s[15] ^= (~lane[1]) & lane[2];
129 s[16] ^= (~lane[2]) & lane[3];
130 s[17] ^= (~lane[3]) & lane[4];
131 s[18] ^= (~lane[4]) & lane[0];
132 s[19] ^= (~lane[0]) & lane[1];
133
134 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
135 s[20] ^= (~lane[1]) & lane[2];
136 s[21] ^= (~lane[2]) & lane[3];
137 s[22] ^= (~lane[3]) & lane[4];
138 s[23] ^= (~lane[4]) & lane[0];
139 s[24] ^= (~lane[0]) & lane[1];
140
141 /* Iota */
142 s[0] ^= rc[round];
143 }
144}
145
Pol Henarejosa6779282023-02-08 00:50:04 +0100146void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200147{
Pol Henarejosa6779282023-02-08 00:50:04 +0100148 memset(ctx, 0, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200149}
150
Pol Henarejosa6779282023-02-08 00:50:04 +0100151void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200152{
Pol Henarejosa6779282023-02-08 00:50:04 +0100153 if (ctx == NULL) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200154 return;
Pol Henarejosa6779282023-02-08 00:50:04 +0100155 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200156
Pol Henarejosa6779282023-02-08 00:50:04 +0100157 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200158}
159
Pol Henarejosa6779282023-02-08 00:50:04 +0100160void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
161 const mbedtls_sha3_context *src)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200162{
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200163 *dst = *src;
164}
165
166/*
167 * SHA-3 context setup
168 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100169int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200170{
Gilles Peskinea3172d12024-02-08 10:47:08 +0100171 switch (id) {
172 case MBEDTLS_SHA3_224:
173 ctx->olen = 224 / 8;
174 ctx->max_block_size = 1152 / 8;
Pol Henarejosa6779282023-02-08 00:50:04 +0100175 break;
Gilles Peskinea3172d12024-02-08 10:47:08 +0100176 case MBEDTLS_SHA3_256:
177 ctx->olen = 256 / 8;
178 ctx->max_block_size = 1088 / 8;
179 break;
180 case MBEDTLS_SHA3_384:
181 ctx->olen = 384 / 8;
182 ctx->max_block_size = 832 / 8;
183 break;
184 case MBEDTLS_SHA3_512:
185 ctx->olen = 512 / 8;
186 ctx->max_block_size = 576 / 8;
187 break;
188 default:
189 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
Pol Henarejosa6779282023-02-08 00:50:04 +0100190 }
191
Pol Henarejosa6779282023-02-08 00:50:04 +0100192 memset(ctx->state, 0, sizeof(ctx->state));
Pol Henarejos938b5ab2022-05-20 16:01:07 +0200193 ctx->index = 0;
194
Pol Henarejosa6779282023-02-08 00:50:04 +0100195 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200196}
197
198/*
199 * SHA-3 process buffer
200 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100201int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
202 const uint8_t *input,
203 size_t ilen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200204{
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100205 if (ilen >= 8) {
206 // 8-byte align index
207 int align_bytes = 8 - (ctx->index % 8);
208 if (align_bytes) {
209 for (; align_bytes > 0; align_bytes--) {
210 ABSORB(ctx, ctx->index, *input++);
211 ilen--;
212 ctx->index++;
213 }
214 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
215 keccak_f1600(ctx);
216 }
217 }
218
219 // process input in 8-byte chunks
220 while (ilen >= 8) {
Dave Rodgman2c91f4b2023-06-07 19:59:05 +0100221 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
Dave Rodgmanbcfd79c2023-05-29 22:04:18 +0100222 input += 8;
223 ilen -= 8;
224 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
225 keccak_f1600(ctx);
226 }
227 }
228 }
229
230 // handle remaining bytes
Pol Henarejosa6779282023-02-08 00:50:04 +0100231 while (ilen-- > 0) {
232 ABSORB(ctx, ctx->index, *input++);
233 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
234 keccak_f1600(ctx);
235 }
236 }
237
238 return 0;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200239}
240
Pol Henarejosa6779282023-02-08 00:50:04 +0100241int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
242 uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200243{
Dave Rodgmandbddb002023-08-30 18:43:23 +0100244 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
245
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200246 /* Catch SHA-3 families, with fixed output length */
Pol Henarejosa6779282023-02-08 00:50:04 +0100247 if (ctx->olen > 0) {
248 if (ctx->olen > olen) {
Dave Rodgmandbddb002023-08-30 18:43:23 +0100249 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
250 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100251 }
Pol Henarejos1f3ae162022-05-17 12:53:30 +0200252 olen = ctx->olen;
253 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200254
Dave Rodgman1789d842023-05-29 22:05:19 +0100255 ABSORB(ctx, ctx->index, XOR_BYTE);
Pol Henarejosa6779282023-02-08 00:50:04 +0100256 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
257 keccak_f1600(ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200258 ctx->index = 0;
259
Pol Henarejosa6779282023-02-08 00:50:04 +0100260 while (olen-- > 0) {
261 *output++ = SQUEEZE(ctx, ctx->index);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200262
Pol Henarejosa6779282023-02-08 00:50:04 +0100263 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
264 keccak_f1600(ctx);
265 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200266 }
267
Dave Rodgmandbddb002023-08-30 18:43:23 +0100268 ret = 0;
269
270exit:
Dave Rodgman984309c2023-08-30 19:22:28 +0100271 mbedtls_sha3_free(ctx);
Dave Rodgmandbddb002023-08-30 18:43:23 +0100272 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200273}
274
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200275/*
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100276 * output = SHA-3( input buffer )
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200277 */
Pol Henarejosa6779282023-02-08 00:50:04 +0100278int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
279 size_t ilen, uint8_t *output, size_t olen)
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200280{
281 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
282 mbedtls_sha3_context ctx;
283
Pol Henarejosa6779282023-02-08 00:50:04 +0100284 mbedtls_sha3_init(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200285
Pol Henarejos85eeda02022-05-17 11:43:15 +0200286 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
Pol Henarejosa6779282023-02-08 00:50:04 +0100287 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 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_update(&ctx, input, ilen)) != 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
Pol Henarejosa6779282023-02-08 00:50:04 +0100295 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200296 goto exit;
Pol Henarejosa6779282023-02-08 00:50:04 +0100297 }
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200298
299exit:
Pol Henarejosa6779282023-02-08 00:50:04 +0100300 mbedtls_sha3_free(&ctx);
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200301
Pol Henarejosa6779282023-02-08 00:50:04 +0100302 return ret;
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200303}
304
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200305/**************** Self-tests ****************/
306
307#if defined(MBEDTLS_SELF_TEST)
308
309static const unsigned char test_data[2][4] =
310{
311 "",
312 "abc",
313};
314
315static const size_t test_data_len[2] =
316{
317 0, /* "" */
318 3 /* "abc" */
319};
320
321static const unsigned char test_hash_sha3_224[2][28] =
322{
323 { /* "" */
324 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
325 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
326 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
327 0x5B, 0x5A, 0x6B, 0xC7
328 },
329 { /* "abc" */
330 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
331 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
332 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
333 0x73, 0xB4, 0x6F, 0xDF
334 }
335};
336
337static const unsigned char test_hash_sha3_256[2][32] =
338{
339 { /* "" */
340 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
341 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
342 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
343 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
344 },
345 { /* "abc" */
346 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
347 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
348 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
349 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
350 }
351};
352
353static const unsigned char test_hash_sha3_384[2][48] =
354{
355 { /* "" */
356 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
357 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
358 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
359 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
360 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
361 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
362 },
363 { /* "abc" */
364 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
365 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
366 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
367 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
368 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
369 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
370 }
371};
372
373static const unsigned char test_hash_sha3_512[2][64] =
374{
375 { /* "" */
376 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
377 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
378 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
379 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
380 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
381 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
382 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
383 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
384 },
385 { /* "abc" */
386 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
387 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
388 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
389 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
390 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
391 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
392 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
393 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
394 }
395};
396
397static const unsigned char long_kat_hash_sha3_224[28] =
398{
399 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
400 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
401 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
402 0xA7, 0xFD, 0x65, 0x3C
403};
404
405static const unsigned char long_kat_hash_sha3_256[32] =
406{
407 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
408 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
409 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
410 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
411};
412
413static const unsigned char long_kat_hash_sha3_384[48] =
414{
415 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
416 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
417 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
418 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
419 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
420 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
421};
422
423static const unsigned char long_kat_hash_sha3_512[64] =
424{
425 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
426 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
427 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
428 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
429 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
430 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
431 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
432 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
433};
434
Pol Henarejosa6779282023-02-08 00:50:04 +0100435static int mbedtls_sha3_kat_test(int verbose,
436 const char *type_name,
437 mbedtls_sha3_id id,
438 int test_num)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200439{
440 uint8_t hash[64];
441 int result;
442
Pol Henarejosa6779282023-02-08 00:50:04 +0100443 result = mbedtls_sha3(id,
444 test_data[test_num], test_data_len[test_num],
445 hash, sizeof(hash));
446 if (result != 0) {
447 if (verbose != 0) {
448 mbedtls_printf(" %s test %d error code: %d\n",
449 type_name, test_num, result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200450 }
451
Pol Henarejosa6779282023-02-08 00:50:04 +0100452 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200453 }
454
Pol Henarejosa6779282023-02-08 00:50:04 +0100455 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200456 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100457 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200458 break;
459 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100460 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200461 break;
462 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100463 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200464 break;
465 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100466 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200467 break;
468 default:
469 break;
470 }
471
Pol Henarejosa6779282023-02-08 00:50:04 +0100472 if (0 != result) {
473 if (verbose != 0) {
474 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200475 }
476
Pol Henarejosa6779282023-02-08 00:50:04 +0100477 return -1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200478 }
479
Pol Henarejosa6779282023-02-08 00:50:04 +0100480 if (verbose != 0) {
481 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200482 }
483
Pol Henarejosa6779282023-02-08 00:50:04 +0100484 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200485}
486
Pol Henarejosa6779282023-02-08 00:50:04 +0100487static int mbedtls_sha3_long_kat_test(int verbose,
488 const char *type_name,
489 mbedtls_sha3_id id)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200490{
491 mbedtls_sha3_context ctx;
492 unsigned char buffer[1000];
493 unsigned char hash[64];
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200494 int result = 0;
495
Pol Henarejosa6779282023-02-08 00:50:04 +0100496 memset(buffer, 'a', 1000);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200497
Pol Henarejosa6779282023-02-08 00:50:04 +0100498 if (verbose != 0) {
499 mbedtls_printf(" %s long KAT test ", type_name);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200500 }
501
Pol Henarejosa6779282023-02-08 00:50:04 +0100502 mbedtls_sha3_init(&ctx);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200503
Pol Henarejosa6779282023-02-08 00:50:04 +0100504 result = mbedtls_sha3_starts(&ctx, id);
505 if (result != 0) {
506 if (verbose != 0) {
507 mbedtls_printf("setup failed\n ");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200508 }
509 }
510
511 /* Process 1,000,000 (one million) 'a' characters */
Dave Rodgmanf213d0a2023-06-07 17:09:47 +0100512 for (int i = 0; i < 1000; i++) {
Pol Henarejosa6779282023-02-08 00:50:04 +0100513 result = mbedtls_sha3_update(&ctx, buffer, 1000);
514 if (result != 0) {
515 if (verbose != 0) {
516 mbedtls_printf("update error code: %i\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200517 }
518
519 goto cleanup;
520 }
521 }
522
Pol Henarejosa6779282023-02-08 00:50:04 +0100523 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
524 if (result != 0) {
525 if (verbose != 0) {
526 mbedtls_printf("finish error code: %d\n", result);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200527 }
528
529 goto cleanup;
530 }
531
Pol Henarejosa6779282023-02-08 00:50:04 +0100532 switch (id) {
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200533 case MBEDTLS_SHA3_224:
Pol Henarejosa6779282023-02-08 00:50:04 +0100534 result = memcmp(hash, long_kat_hash_sha3_224, 28);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200535 break;
536 case MBEDTLS_SHA3_256:
Pol Henarejosa6779282023-02-08 00:50:04 +0100537 result = memcmp(hash, long_kat_hash_sha3_256, 32);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200538 break;
539 case MBEDTLS_SHA3_384:
Pol Henarejosa6779282023-02-08 00:50:04 +0100540 result = memcmp(hash, long_kat_hash_sha3_384, 48);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200541 break;
542 case MBEDTLS_SHA3_512:
Pol Henarejosa6779282023-02-08 00:50:04 +0100543 result = memcmp(hash, long_kat_hash_sha3_512, 64);
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200544 break;
545 default:
546 break;
547 }
548
Pol Henarejosa6779282023-02-08 00:50:04 +0100549 if (result != 0) {
550 if (verbose != 0) {
551 mbedtls_printf("failed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200552 }
553 }
554
Pol Henarejosa6779282023-02-08 00:50:04 +0100555 if (verbose != 0) {
556 mbedtls_printf("passed\n");
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200557 }
558
559cleanup:
Pol Henarejosa6779282023-02-08 00:50:04 +0100560 mbedtls_sha3_free(&ctx);
561 return result;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200562}
563
Pol Henarejosa6779282023-02-08 00:50:04 +0100564int mbedtls_sha3_self_test(int verbose)
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200565{
566 int i;
567
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100568 /* SHA-3 Known Answer Tests (KAT) */
Pol Henarejosa6779282023-02-08 00:50:04 +0100569 for (i = 0; i < 2; i++) {
570 if (0 != mbedtls_sha3_kat_test(verbose,
571 "SHA3-224", MBEDTLS_SHA3_224, i)) {
572 return 1;
573 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200574
Pol Henarejosa6779282023-02-08 00:50:04 +0100575 if (0 != mbedtls_sha3_kat_test(verbose,
576 "SHA3-256", MBEDTLS_SHA3_256, i)) {
577 return 1;
578 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200579
Pol Henarejosa6779282023-02-08 00:50:04 +0100580 if (0 != mbedtls_sha3_kat_test(verbose,
581 "SHA3-384", MBEDTLS_SHA3_384, i)) {
582 return 1;
583 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200584
Pol Henarejosa6779282023-02-08 00:50:04 +0100585 if (0 != mbedtls_sha3_kat_test(verbose,
586 "SHA3-512", MBEDTLS_SHA3_512, i)) {
587 return 1;
588 }
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200589 }
590
Dave Rodgmancf4d2bd2023-06-07 17:08:09 +0100591 /* SHA-3 long KAT tests */
Pol Henarejosa6779282023-02-08 00:50:04 +0100592 if (0 != mbedtls_sha3_long_kat_test(verbose,
593 "SHA3-224", MBEDTLS_SHA3_224)) {
594 return 1;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200595 }
596
Pol Henarejosa6779282023-02-08 00:50:04 +0100597 if (0 != mbedtls_sha3_long_kat_test(verbose,
598 "SHA3-256", MBEDTLS_SHA3_256)) {
599 return 1;
600 }
601
602 if (0 != mbedtls_sha3_long_kat_test(verbose,
603 "SHA3-384", MBEDTLS_SHA3_384)) {
604 return 1;
605 }
606
607 if (0 != mbedtls_sha3_long_kat_test(verbose,
608 "SHA3-512", MBEDTLS_SHA3_512)) {
609 return 1;
610 }
611
612 if (verbose != 0) {
613 mbedtls_printf("\n");
614 }
615
616 return 0;
Pol Henarejos7dbd5d12022-05-20 20:42:33 +0200617}
618#endif /* MBEDTLS_SELF_TEST */
619
Pol Henarejos0cd1f1c2022-05-09 01:04:15 +0200620#endif /* MBEDTLS_SHA3_C */