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