1 /*
2 * FIPS-202 compliant SHA3 implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
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 /*
18 * These macros select manually unrolled implementations of parts of the main permutation function.
19 *
20 * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
21 * from manually unrolling at higher optimisation levels.
22 *
23 * Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust
24 * these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and
25 * x86-64.
26 */
27 #if !defined(MBEDTLS_SHA3_THETA_UNROLL)
28 #define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names
29 #endif
30 #if !defined(MBEDTLS_SHA3_CHI_UNROLL)
31 #if defined(__OPTIMIZE_SIZE__)
32 #define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names
33 #else
34 #define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names
35 #endif
36 #endif
37 #if !defined(MBEDTLS_SHA3_PI_UNROLL)
38 #define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names
39 #endif
40 #if !defined(MBEDTLS_SHA3_RHO_UNROLL)
41 #define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names
42 #endif
43
44 #include "mbedtls/sha3.h"
45 #include "mbedtls/platform_util.h"
46 #include "mbedtls/error.h"
47
48 #include <string.h>
49
50 #if defined(MBEDTLS_SELF_TEST)
51 #include "mbedtls/platform.h"
52 #endif /* MBEDTLS_SELF_TEST */
53
54 #define XOR_BYTE 0x6
55
56 /* Precomputed masks for the iota transform.
57 *
58 * Each round uses a 64-bit mask value. In each mask values, only
59 * bits whose position is of the form 2^k-1 can be set, thus only
60 * 7 of 64 bits of the mask need to be known for each mask value.
61 *
62 * We use a compressed encoding of the mask where bits 63, 31 and 15
63 * are moved to bits 4-6. This allows us to make each mask value
64 * 1 byte rather than 8 bytes, saving 7*24 = 168 bytes of data (with
65 * perhaps a little variation due to alignment). Decompressing this
66 * requires a little code, but much less than the savings on the table.
67 *
68 * The impact on performance depends on the platform and compiler.
69 * There's a bit more computation, but less memory bandwidth. A quick
70 * benchmark on x86_64 shows a 7% speed improvement with GCC and a
71 * 5% speed penalty with Clang, compared to the naive uint64_t[24] table.
72 * YMMV.
73 */
74 /* Helper macro to set the values of the higher bits in unused low positions */
75 #define H(b63, b31, b15) (b63 << 6 | b31 << 5 | b15 << 4)
76 static const uint8_t iota_r_packed[24] = {
77 H(0, 0, 0) | 0x01, H(0, 0, 1) | 0x82, H(1, 0, 1) | 0x8a, H(1, 1, 1) | 0x00,
78 H(0, 0, 1) | 0x8b, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x09,
79 H(0, 0, 0) | 0x8a, H(0, 0, 0) | 0x88, H(0, 1, 1) | 0x09, H(0, 1, 0) | 0x0a,
80 H(0, 1, 1) | 0x8b, H(1, 0, 0) | 0x8b, H(1, 0, 1) | 0x89, H(1, 0, 1) | 0x03,
81 H(1, 0, 1) | 0x02, H(1, 0, 0) | 0x80, H(0, 0, 1) | 0x0a, H(1, 1, 0) | 0x0a,
82 H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x80, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x08,
83 };
84 #undef H
85
86 static const uint32_t rho[6] = {
87 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
88 };
89
90 static const uint32_t pi[6] = {
91 0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916
92 };
93
94 #define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
95 #define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
96 } while (0)
97 #define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
98 #define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
99
100 /* The permutation function. */
keccak_f1600(mbedtls_sha3_context * ctx)101 static void keccak_f1600(mbedtls_sha3_context *ctx)
102 {
103 uint64_t lane[5];
104 uint64_t *s = ctx->state;
105 int i;
106
107 for (int round = 0; round < 24; round++) {
108 uint64_t t;
109
110 /* Theta */
111 #if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
112 for (i = 0; i < 5; i++) {
113 lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
114 }
115 for (i = 0; i < 5; i++) {
116 t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
117 s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
118 }
119 #else
120 lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
121 lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
122 lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
123 lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
124 lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
125
126 t = lane[4] ^ ROTR64(lane[1], 63);
127 s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
128
129 t = lane[0] ^ ROTR64(lane[2], 63);
130 s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
131
132 t = lane[1] ^ ROTR64(lane[3], 63);
133 s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
134
135 t = lane[2] ^ ROTR64(lane[4], 63);
136 s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
137
138 t = lane[3] ^ ROTR64(lane[0], 63);
139 s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
140 #endif
141
142 /* Rho */
143 for (i = 1; i < 25; i += 4) {
144 uint32_t r = rho[(i - 1) >> 2];
145 #if MBEDTLS_SHA3_RHO_UNROLL == 0
146 for (int j = i; j < i + 4; j++) {
147 uint8_t r8 = (uint8_t) (r >> 24);
148 r <<= 8;
149 s[j] = ROTR64(s[j], r8);
150 }
151 #else
152 s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
153 s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
154 s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
155 s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
156 #endif
157 }
158
159 /* Pi */
160 t = s[1];
161 #if MBEDTLS_SHA3_PI_UNROLL == 0
162 for (i = 0; i < 24; i += 4) {
163 uint32_t p = pi[i >> 2];
164 for (unsigned j = 0; j < 4; j++) {
165 SWAP(s[p & 0xff], t);
166 p >>= 8;
167 }
168 }
169 #else
170 uint32_t p = pi[0];
171 SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
172 SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
173 p = pi[1];
174 SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
175 SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
176 p = pi[2];
177 SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
178 SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
179 p = pi[3];
180 SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
181 SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
182 p = pi[4];
183 SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
184 SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
185 p = pi[5];
186 SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
187 SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
188 #endif
189
190 /* Chi */
191 #if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names
192 for (i = 0; i <= 20; i += 5) {
193 lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2];
194 lane[3] = s[i + 3]; lane[4] = s[i + 4];
195 s[i + 0] ^= (~lane[1]) & lane[2];
196 s[i + 1] ^= (~lane[2]) & lane[3];
197 s[i + 2] ^= (~lane[3]) & lane[4];
198 s[i + 3] ^= (~lane[4]) & lane[0];
199 s[i + 4] ^= (~lane[0]) & lane[1];
200 }
201 #else
202 lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
203 s[0] ^= (~lane[1]) & lane[2];
204 s[1] ^= (~lane[2]) & lane[3];
205 s[2] ^= (~lane[3]) & lane[4];
206 s[3] ^= (~lane[4]) & lane[0];
207 s[4] ^= (~lane[0]) & lane[1];
208
209 lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
210 s[5] ^= (~lane[1]) & lane[2];
211 s[6] ^= (~lane[2]) & lane[3];
212 s[7] ^= (~lane[3]) & lane[4];
213 s[8] ^= (~lane[4]) & lane[0];
214 s[9] ^= (~lane[0]) & lane[1];
215
216 lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
217 s[10] ^= (~lane[1]) & lane[2];
218 s[11] ^= (~lane[2]) & lane[3];
219 s[12] ^= (~lane[3]) & lane[4];
220 s[13] ^= (~lane[4]) & lane[0];
221 s[14] ^= (~lane[0]) & lane[1];
222
223 lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
224 s[15] ^= (~lane[1]) & lane[2];
225 s[16] ^= (~lane[2]) & lane[3];
226 s[17] ^= (~lane[3]) & lane[4];
227 s[18] ^= (~lane[4]) & lane[0];
228 s[19] ^= (~lane[0]) & lane[1];
229
230 lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
231 s[20] ^= (~lane[1]) & lane[2];
232 s[21] ^= (~lane[2]) & lane[3];
233 s[22] ^= (~lane[3]) & lane[4];
234 s[23] ^= (~lane[4]) & lane[0];
235 s[24] ^= (~lane[0]) & lane[1];
236 #endif
237
238 /* Iota */
239 /* Decompress the round masks (see definition of rc) */
240 s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
241 (iota_r_packed[round] & 0x20ull) << 26 |
242 (iota_r_packed[round] & 0x10ull) << 11 |
243 (iota_r_packed[round] & 0x8f));
244 }
245 }
246
mbedtls_sha3_init(mbedtls_sha3_context * ctx)247 void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
248 {
249 memset(ctx, 0, sizeof(mbedtls_sha3_context));
250 }
251
mbedtls_sha3_free(mbedtls_sha3_context * ctx)252 void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
253 {
254 if (ctx == NULL) {
255 return;
256 }
257
258 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
259 }
260
mbedtls_sha3_clone(mbedtls_sha3_context * dst,const mbedtls_sha3_context * src)261 void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
262 const mbedtls_sha3_context *src)
263 {
264 *dst = *src;
265 }
266
267 /*
268 * SHA-3 context setup
269 */
mbedtls_sha3_starts(mbedtls_sha3_context * ctx,mbedtls_sha3_id id)270 int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
271 {
272 switch (id) {
273 case MBEDTLS_SHA3_224:
274 ctx->olen = 224 / 8;
275 ctx->max_block_size = 1152 / 8;
276 break;
277 case MBEDTLS_SHA3_256:
278 ctx->olen = 256 / 8;
279 ctx->max_block_size = 1088 / 8;
280 break;
281 case MBEDTLS_SHA3_384:
282 ctx->olen = 384 / 8;
283 ctx->max_block_size = 832 / 8;
284 break;
285 case MBEDTLS_SHA3_512:
286 ctx->olen = 512 / 8;
287 ctx->max_block_size = 576 / 8;
288 break;
289 default:
290 return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
291 }
292
293 memset(ctx->state, 0, sizeof(ctx->state));
294 ctx->index = 0;
295
296 return 0;
297 }
298
299 /*
300 * SHA-3 process buffer
301 */
mbedtls_sha3_update(mbedtls_sha3_context * ctx,const uint8_t * input,size_t ilen)302 int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
303 const uint8_t *input,
304 size_t ilen)
305 {
306 if (ilen >= 8) {
307 // 8-byte align index
308 int align_bytes = 8 - (ctx->index % 8);
309 if (align_bytes) {
310 for (; align_bytes > 0; align_bytes--) {
311 ABSORB(ctx, ctx->index, *input++);
312 ilen--;
313 ctx->index++;
314 }
315 if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
316 keccak_f1600(ctx);
317 }
318 }
319
320 // process input in 8-byte chunks
321 while (ilen >= 8) {
322 ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
323 input += 8;
324 ilen -= 8;
325 if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
326 keccak_f1600(ctx);
327 }
328 }
329 }
330
331 // handle remaining bytes
332 while (ilen-- > 0) {
333 ABSORB(ctx, ctx->index, *input++);
334 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
335 keccak_f1600(ctx);
336 }
337 }
338
339 return 0;
340 }
341
mbedtls_sha3_finish(mbedtls_sha3_context * ctx,uint8_t * output,size_t olen)342 int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
343 uint8_t *output, size_t olen)
344 {
345 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
346
347 /* Catch SHA-3 families, with fixed output length */
348 if (ctx->olen > 0) {
349 if (ctx->olen > olen) {
350 ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
351 goto exit;
352 }
353 olen = ctx->olen;
354 }
355
356 ABSORB(ctx, ctx->index, XOR_BYTE);
357 ABSORB(ctx, ctx->max_block_size - 1, 0x80);
358 keccak_f1600(ctx);
359 ctx->index = 0;
360
361 while (olen-- > 0) {
362 *output++ = SQUEEZE(ctx, ctx->index);
363
364 if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
365 keccak_f1600(ctx);
366 }
367 }
368
369 ret = 0;
370
371 exit:
372 mbedtls_sha3_free(ctx);
373 return ret;
374 }
375
376 /*
377 * output = SHA-3( input buffer )
378 */
mbedtls_sha3(mbedtls_sha3_id id,const uint8_t * input,size_t ilen,uint8_t * output,size_t olen)379 int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
380 size_t ilen, uint8_t *output, size_t olen)
381 {
382 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
383 mbedtls_sha3_context ctx;
384
385 mbedtls_sha3_init(&ctx);
386
387 /* Sanity checks are performed in every mbedtls_sha3_xxx() */
388 if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
389 goto exit;
390 }
391
392 if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
393 goto exit;
394 }
395
396 if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
397 goto exit;
398 }
399
400 exit:
401 mbedtls_sha3_free(&ctx);
402
403 return ret;
404 }
405
406 /**************** Self-tests ****************/
407
408 #if defined(MBEDTLS_SELF_TEST)
409
410 static const unsigned char test_data[2][4] =
411 {
412 "",
413 "abc",
414 };
415
416 static const size_t test_data_len[2] =
417 {
418 0, /* "" */
419 3 /* "abc" */
420 };
421
422 static const unsigned char test_hash_sha3_224[2][28] =
423 {
424 { /* "" */
425 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
426 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
427 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
428 0x5B, 0x5A, 0x6B, 0xC7
429 },
430 { /* "abc" */
431 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
432 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
433 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
434 0x73, 0xB4, 0x6F, 0xDF
435 }
436 };
437
438 static const unsigned char test_hash_sha3_256[2][32] =
439 {
440 { /* "" */
441 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
442 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
443 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
444 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
445 },
446 { /* "abc" */
447 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
448 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
449 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
450 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
451 }
452 };
453
454 static const unsigned char test_hash_sha3_384[2][48] =
455 {
456 { /* "" */
457 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
458 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
459 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
460 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
461 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
462 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
463 },
464 { /* "abc" */
465 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
466 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
467 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
468 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
469 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
470 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
471 }
472 };
473
474 static const unsigned char test_hash_sha3_512[2][64] =
475 {
476 { /* "" */
477 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
478 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
479 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
480 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
481 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
482 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
483 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
484 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
485 },
486 { /* "abc" */
487 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
488 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
489 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
490 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
491 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
492 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
493 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
494 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
495 }
496 };
497
498 static const unsigned char long_kat_hash_sha3_224[28] =
499 {
500 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
501 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
502 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
503 0xA7, 0xFD, 0x65, 0x3C
504 };
505
506 static const unsigned char long_kat_hash_sha3_256[32] =
507 {
508 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
509 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
510 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
511 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
512 };
513
514 static const unsigned char long_kat_hash_sha3_384[48] =
515 {
516 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
517 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
518 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
519 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
520 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
521 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
522 };
523
524 static const unsigned char long_kat_hash_sha3_512[64] =
525 {
526 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
527 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
528 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
529 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
530 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
531 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
532 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
533 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
534 };
535
mbedtls_sha3_kat_test(int verbose,const char * type_name,mbedtls_sha3_id id,int test_num)536 static int mbedtls_sha3_kat_test(int verbose,
537 const char *type_name,
538 mbedtls_sha3_id id,
539 int test_num)
540 {
541 uint8_t hash[64];
542 int result;
543
544 result = mbedtls_sha3(id,
545 test_data[test_num], test_data_len[test_num],
546 hash, sizeof(hash));
547 if (result != 0) {
548 if (verbose != 0) {
549 mbedtls_printf(" %s test %d error code: %d\n",
550 type_name, test_num, result);
551 }
552
553 return result;
554 }
555
556 switch (id) {
557 case MBEDTLS_SHA3_224:
558 result = memcmp(hash, test_hash_sha3_224[test_num], 28);
559 break;
560 case MBEDTLS_SHA3_256:
561 result = memcmp(hash, test_hash_sha3_256[test_num], 32);
562 break;
563 case MBEDTLS_SHA3_384:
564 result = memcmp(hash, test_hash_sha3_384[test_num], 48);
565 break;
566 case MBEDTLS_SHA3_512:
567 result = memcmp(hash, test_hash_sha3_512[test_num], 64);
568 break;
569 default:
570 break;
571 }
572
573 if (0 != result) {
574 if (verbose != 0) {
575 mbedtls_printf(" %s test %d failed\n", type_name, test_num);
576 }
577
578 return -1;
579 }
580
581 if (verbose != 0) {
582 mbedtls_printf(" %s test %d passed\n", type_name, test_num);
583 }
584
585 return 0;
586 }
587
mbedtls_sha3_long_kat_test(int verbose,const char * type_name,mbedtls_sha3_id id)588 static int mbedtls_sha3_long_kat_test(int verbose,
589 const char *type_name,
590 mbedtls_sha3_id id)
591 {
592 mbedtls_sha3_context ctx;
593 unsigned char buffer[1000];
594 unsigned char hash[64];
595 int result = 0;
596
597 memset(buffer, 'a', 1000);
598
599 if (verbose != 0) {
600 mbedtls_printf(" %s long KAT test ", type_name);
601 }
602
603 mbedtls_sha3_init(&ctx);
604
605 result = mbedtls_sha3_starts(&ctx, id);
606 if (result != 0) {
607 if (verbose != 0) {
608 mbedtls_printf("setup failed\n ");
609 }
610 }
611
612 /* Process 1,000,000 (one million) 'a' characters */
613 for (int i = 0; i < 1000; i++) {
614 result = mbedtls_sha3_update(&ctx, buffer, 1000);
615 if (result != 0) {
616 if (verbose != 0) {
617 mbedtls_printf("update error code: %i\n", result);
618 }
619
620 goto cleanup;
621 }
622 }
623
624 result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
625 if (result != 0) {
626 if (verbose != 0) {
627 mbedtls_printf("finish error code: %d\n", result);
628 }
629
630 goto cleanup;
631 }
632
633 switch (id) {
634 case MBEDTLS_SHA3_224:
635 result = memcmp(hash, long_kat_hash_sha3_224, 28);
636 break;
637 case MBEDTLS_SHA3_256:
638 result = memcmp(hash, long_kat_hash_sha3_256, 32);
639 break;
640 case MBEDTLS_SHA3_384:
641 result = memcmp(hash, long_kat_hash_sha3_384, 48);
642 break;
643 case MBEDTLS_SHA3_512:
644 result = memcmp(hash, long_kat_hash_sha3_512, 64);
645 break;
646 default:
647 break;
648 }
649
650 if (result != 0) {
651 if (verbose != 0) {
652 mbedtls_printf("failed\n");
653 }
654 }
655
656 if (verbose != 0) {
657 mbedtls_printf("passed\n");
658 }
659
660 cleanup:
661 mbedtls_sha3_free(&ctx);
662 return result;
663 }
664
mbedtls_sha3_self_test(int verbose)665 int mbedtls_sha3_self_test(int verbose)
666 {
667 int i;
668
669 /* SHA-3 Known Answer Tests (KAT) */
670 for (i = 0; i < 2; i++) {
671 if (0 != mbedtls_sha3_kat_test(verbose,
672 "SHA3-224", MBEDTLS_SHA3_224, i)) {
673 return 1;
674 }
675
676 if (0 != mbedtls_sha3_kat_test(verbose,
677 "SHA3-256", MBEDTLS_SHA3_256, i)) {
678 return 1;
679 }
680
681 if (0 != mbedtls_sha3_kat_test(verbose,
682 "SHA3-384", MBEDTLS_SHA3_384, i)) {
683 return 1;
684 }
685
686 if (0 != mbedtls_sha3_kat_test(verbose,
687 "SHA3-512", MBEDTLS_SHA3_512, i)) {
688 return 1;
689 }
690 }
691
692 /* SHA-3 long KAT tests */
693 if (0 != mbedtls_sha3_long_kat_test(verbose,
694 "SHA3-224", MBEDTLS_SHA3_224)) {
695 return 1;
696 }
697
698 if (0 != mbedtls_sha3_long_kat_test(verbose,
699 "SHA3-256", MBEDTLS_SHA3_256)) {
700 return 1;
701 }
702
703 if (0 != mbedtls_sha3_long_kat_test(verbose,
704 "SHA3-384", MBEDTLS_SHA3_384)) {
705 return 1;
706 }
707
708 if (0 != mbedtls_sha3_long_kat_test(verbose,
709 "SHA3-512", MBEDTLS_SHA3_512)) {
710 return 1;
711 }
712
713 if (verbose != 0) {
714 mbedtls_printf("\n");
715 }
716
717 return 0;
718 }
719 #endif /* MBEDTLS_SELF_TEST */
720
721 #endif /* MBEDTLS_SHA3_C */
722