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 #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)
24 #include "mbedtls/platform.h"
25 #endif /* MBEDTLS_SELF_TEST */
26 
27 #define XOR_BYTE 0x6
28 
29 typedef struct mbedtls_sha3_family_functions {
30     mbedtls_sha3_id id;
31 
32     uint16_t r;
33     uint16_t olen;
34 }
35 mbedtls_sha3_family_functions;
36 
37 /*
38  * List of supported SHA-3 families
39  */
40 static mbedtls_sha3_family_functions sha3_families[] = {
41     { MBEDTLS_SHA3_224,      1152, 224 },
42     { MBEDTLS_SHA3_256,      1088, 256 },
43     { MBEDTLS_SHA3_384,       832, 384 },
44     { MBEDTLS_SHA3_512,       576, 512 },
45     { MBEDTLS_SHA3_NONE, 0, 0 }
46 };
47 
48 static const uint64_t rc[24] = {
49     0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
50     0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
51     0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
52     0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
53     0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
54     0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
55 };
56 
57 static const uint8_t rho[24] = {
58     1, 62, 28, 27, 36, 44,  6, 55, 20,
59     3, 10, 43, 25, 39, 41, 45, 15,
60     21,  8, 18,  2, 61, 56, 14
61 };
62 
63 static const uint8_t pi[24] = {
64     10,  7, 11, 17, 18, 3,  5, 16,  8, 21, 24, 4,
65     15, 23, 19, 13, 12, 2, 20, 14, 22,  9,  6, 1,
66 };
67 
68 #define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
69 #define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
70 } while (0)
71 #define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
72 #define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
73 
74 /* The permutation function.  */
keccak_f1600(mbedtls_sha3_context * ctx)75 static void keccak_f1600(mbedtls_sha3_context *ctx)
76 {
77     uint64_t lane[5];
78     uint64_t *s = ctx->state;
79     int i;
80 
81     for (int round = 0; round < 24; round++) {
82         uint64_t t;
83 
84         /* Theta */
85         lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
86         lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
87         lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
88         lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
89         lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
90 
91         t = lane[4] ^ ROT64(lane[1], 1);
92         s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
93 
94         t = lane[0] ^ ROT64(lane[2], 1);
95         s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
96 
97         t = lane[1] ^ ROT64(lane[3], 1);
98         s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
99 
100         t = lane[2] ^ ROT64(lane[4], 1);
101         s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
102 
103         t = lane[3] ^ ROT64(lane[0], 1);
104         s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
105 
106         /* Rho */
107         for (i = 1; i < 25; i++) {
108             s[i] = ROT64(s[i], rho[i-1]);
109         }
110 
111         /* Pi */
112         t = s[1];
113         for (i = 0; i < 24; i++) {
114             SWAP(s[pi[i]], t);
115         }
116 
117         /* Chi */
118         lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
119         s[0] ^= (~lane[1]) & lane[2];
120         s[1] ^= (~lane[2]) & lane[3];
121         s[2] ^= (~lane[3]) & lane[4];
122         s[3] ^= (~lane[4]) & lane[0];
123         s[4] ^= (~lane[0]) & lane[1];
124 
125         lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
126         s[5] ^= (~lane[1]) & lane[2];
127         s[6] ^= (~lane[2]) & lane[3];
128         s[7] ^= (~lane[3]) & lane[4];
129         s[8] ^= (~lane[4]) & lane[0];
130         s[9] ^= (~lane[0]) & lane[1];
131 
132         lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
133         s[10] ^= (~lane[1]) & lane[2];
134         s[11] ^= (~lane[2]) & lane[3];
135         s[12] ^= (~lane[3]) & lane[4];
136         s[13] ^= (~lane[4]) & lane[0];
137         s[14] ^= (~lane[0]) & lane[1];
138 
139         lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
140         s[15] ^= (~lane[1]) & lane[2];
141         s[16] ^= (~lane[2]) & lane[3];
142         s[17] ^= (~lane[3]) & lane[4];
143         s[18] ^= (~lane[4]) & lane[0];
144         s[19] ^= (~lane[0]) & lane[1];
145 
146         lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
147         s[20] ^= (~lane[1]) & lane[2];
148         s[21] ^= (~lane[2]) & lane[3];
149         s[22] ^= (~lane[3]) & lane[4];
150         s[23] ^= (~lane[4]) & lane[0];
151         s[24] ^= (~lane[0]) & lane[1];
152 
153         /* Iota */
154         s[0] ^= rc[round];
155     }
156 }
157 
mbedtls_sha3_init(mbedtls_sha3_context * ctx)158 void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
159 {
160     memset(ctx, 0, sizeof(mbedtls_sha3_context));
161 }
162 
mbedtls_sha3_free(mbedtls_sha3_context * ctx)163 void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
164 {
165     if (ctx == NULL) {
166         return;
167     }
168 
169     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
170 }
171 
mbedtls_sha3_clone(mbedtls_sha3_context * dst,const mbedtls_sha3_context * src)172 void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
173                         const mbedtls_sha3_context *src)
174 {
175     *dst = *src;
176 }
177 
178 /*
179  * SHA-3 context setup
180  */
mbedtls_sha3_starts(mbedtls_sha3_context * ctx,mbedtls_sha3_id id)181 int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
182 {
183     mbedtls_sha3_family_functions *p = NULL;
184 
185     for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) {
186         if (p->id == id) {
187             break;
188         }
189     }
190 
191     if (p->id == MBEDTLS_SHA3_NONE) {
192         return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
193     }
194 
195     ctx->olen = p->olen / 8;
196     ctx->max_block_size = p->r / 8;
197 
198     memset(ctx->state, 0, sizeof(ctx->state));
199     ctx->index = 0;
200 
201     return 0;
202 }
203 
204 /*
205  * SHA-3 process buffer
206  */
mbedtls_sha3_update(mbedtls_sha3_context * ctx,const uint8_t * input,size_t ilen)207 int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
208                         const uint8_t *input,
209                         size_t ilen)
210 {
211     if (ilen >= 8) {
212         // 8-byte align index
213         int align_bytes = 8 - (ctx->index % 8);
214         if (align_bytes) {
215             for (; align_bytes > 0; align_bytes--) {
216                 ABSORB(ctx, ctx->index, *input++);
217                 ilen--;
218                 ctx->index++;
219             }
220             if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
221                 keccak_f1600(ctx);
222             }
223         }
224 
225         // process input in 8-byte chunks
226         while (ilen >= 8) {
227             ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
228             input += 8;
229             ilen -= 8;
230             if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
231                 keccak_f1600(ctx);
232             }
233         }
234     }
235 
236     // handle remaining bytes
237     while (ilen-- > 0) {
238         ABSORB(ctx, ctx->index, *input++);
239         if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
240             keccak_f1600(ctx);
241         }
242     }
243 
244     return 0;
245 }
246 
mbedtls_sha3_finish(mbedtls_sha3_context * ctx,uint8_t * output,size_t olen)247 int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
248                         uint8_t *output, size_t olen)
249 {
250     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
251 
252     /* Catch SHA-3 families, with fixed output length */
253     if (ctx->olen > 0) {
254         if (ctx->olen > olen) {
255             ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
256             goto exit;
257         }
258         olen = ctx->olen;
259     }
260 
261     ABSORB(ctx, ctx->index, XOR_BYTE);
262     ABSORB(ctx, ctx->max_block_size - 1, 0x80);
263     keccak_f1600(ctx);
264     ctx->index = 0;
265 
266     while (olen-- > 0) {
267         *output++ = SQUEEZE(ctx, ctx->index);
268 
269         if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
270             keccak_f1600(ctx);
271         }
272     }
273 
274     ret = 0;
275 
276 exit:
277     mbedtls_sha3_free(ctx);
278     return ret;
279 }
280 
281 /*
282  * output = SHA-3( input buffer )
283  */
mbedtls_sha3(mbedtls_sha3_id id,const uint8_t * input,size_t ilen,uint8_t * output,size_t olen)284 int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
285                  size_t ilen, uint8_t *output, size_t olen)
286 {
287     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
288     mbedtls_sha3_context ctx;
289 
290     mbedtls_sha3_init(&ctx);
291 
292     /* Sanity checks are performed in every mbedtls_sha3_xxx() */
293     if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
294         goto exit;
295     }
296 
297     if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
298         goto exit;
299     }
300 
301     if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
302         goto exit;
303     }
304 
305 exit:
306     mbedtls_sha3_free(&ctx);
307 
308     return ret;
309 }
310 
311 /**************** Self-tests ****************/
312 
313 #if defined(MBEDTLS_SELF_TEST)
314 
315 static const unsigned char test_data[2][4] =
316 {
317     "",
318     "abc",
319 };
320 
321 static const size_t test_data_len[2] =
322 {
323     0, /* "" */
324     3  /* "abc" */
325 };
326 
327 static const unsigned char test_hash_sha3_224[2][28] =
328 {
329     { /* "" */
330         0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
331         0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
332         0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
333         0x5B, 0x5A, 0x6B, 0xC7
334     },
335     { /* "abc" */
336         0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
337         0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
338         0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
339         0x73, 0xB4, 0x6F, 0xDF
340     }
341 };
342 
343 static const unsigned char test_hash_sha3_256[2][32] =
344 {
345     { /* "" */
346         0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
347         0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
348         0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
349         0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
350     },
351     { /* "abc" */
352         0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
353         0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
354         0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
355         0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
356     }
357 };
358 
359 static const unsigned char test_hash_sha3_384[2][48] =
360 {
361     { /* "" */
362         0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
363         0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
364         0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
365         0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
366         0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
367         0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
368     },
369     { /* "abc" */
370         0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
371         0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
372         0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
373         0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
374         0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
375         0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
376     }
377 };
378 
379 static const unsigned char test_hash_sha3_512[2][64] =
380 {
381     { /* "" */
382         0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
383         0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
384         0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
385         0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
386         0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
387         0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
388         0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
389         0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
390     },
391     { /* "abc" */
392         0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
393         0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
394         0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
395         0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
396         0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
397         0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
398         0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
399         0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
400     }
401 };
402 
403 static const unsigned char long_kat_hash_sha3_224[28] =
404 {
405     0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
406     0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
407     0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
408     0xA7, 0xFD, 0x65, 0x3C
409 };
410 
411 static const unsigned char long_kat_hash_sha3_256[32] =
412 {
413     0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
414     0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
415     0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
416     0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
417 };
418 
419 static const unsigned char long_kat_hash_sha3_384[48] =
420 {
421     0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
422     0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
423     0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
424     0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
425     0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
426     0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
427 };
428 
429 static const unsigned char long_kat_hash_sha3_512[64] =
430 {
431     0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
432     0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
433     0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
434     0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
435     0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
436     0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
437     0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
438     0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
439 };
440 
mbedtls_sha3_kat_test(int verbose,const char * type_name,mbedtls_sha3_id id,int test_num)441 static int mbedtls_sha3_kat_test(int verbose,
442                                  const char *type_name,
443                                  mbedtls_sha3_id id,
444                                  int test_num)
445 {
446     uint8_t hash[64];
447     int result;
448 
449     result = mbedtls_sha3(id,
450                           test_data[test_num], test_data_len[test_num],
451                           hash, sizeof(hash));
452     if (result != 0) {
453         if (verbose != 0) {
454             mbedtls_printf("  %s test %d error code: %d\n",
455                            type_name, test_num, result);
456         }
457 
458         return result;
459     }
460 
461     switch (id) {
462         case MBEDTLS_SHA3_224:
463             result = memcmp(hash, test_hash_sha3_224[test_num], 28);
464             break;
465         case MBEDTLS_SHA3_256:
466             result = memcmp(hash, test_hash_sha3_256[test_num], 32);
467             break;
468         case MBEDTLS_SHA3_384:
469             result = memcmp(hash, test_hash_sha3_384[test_num], 48);
470             break;
471         case MBEDTLS_SHA3_512:
472             result = memcmp(hash, test_hash_sha3_512[test_num], 64);
473             break;
474         default:
475             break;
476     }
477 
478     if (0 != result) {
479         if (verbose != 0) {
480             mbedtls_printf("  %s test %d failed\n", type_name, test_num);
481         }
482 
483         return -1;
484     }
485 
486     if (verbose != 0) {
487         mbedtls_printf("  %s test %d passed\n", type_name, test_num);
488     }
489 
490     return 0;
491 }
492 
mbedtls_sha3_long_kat_test(int verbose,const char * type_name,mbedtls_sha3_id id)493 static int mbedtls_sha3_long_kat_test(int verbose,
494                                       const char *type_name,
495                                       mbedtls_sha3_id id)
496 {
497     mbedtls_sha3_context ctx;
498     unsigned char buffer[1000];
499     unsigned char hash[64];
500     int result = 0;
501 
502     memset(buffer, 'a', 1000);
503 
504     if (verbose != 0) {
505         mbedtls_printf("  %s long KAT test ", type_name);
506     }
507 
508     mbedtls_sha3_init(&ctx);
509 
510     result = mbedtls_sha3_starts(&ctx, id);
511     if (result != 0) {
512         if (verbose != 0) {
513             mbedtls_printf("setup failed\n ");
514         }
515     }
516 
517     /* Process 1,000,000 (one million) 'a' characters */
518     for (int i = 0; i < 1000; i++) {
519         result = mbedtls_sha3_update(&ctx, buffer, 1000);
520         if (result != 0) {
521             if (verbose != 0) {
522                 mbedtls_printf("update error code: %i\n", result);
523             }
524 
525             goto cleanup;
526         }
527     }
528 
529     result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
530     if (result != 0) {
531         if (verbose != 0) {
532             mbedtls_printf("finish error code: %d\n", result);
533         }
534 
535         goto cleanup;
536     }
537 
538     switch (id) {
539         case MBEDTLS_SHA3_224:
540             result = memcmp(hash, long_kat_hash_sha3_224, 28);
541             break;
542         case MBEDTLS_SHA3_256:
543             result = memcmp(hash, long_kat_hash_sha3_256, 32);
544             break;
545         case MBEDTLS_SHA3_384:
546             result = memcmp(hash, long_kat_hash_sha3_384, 48);
547             break;
548         case MBEDTLS_SHA3_512:
549             result = memcmp(hash, long_kat_hash_sha3_512, 64);
550             break;
551         default:
552             break;
553     }
554 
555     if (result != 0) {
556         if (verbose != 0) {
557             mbedtls_printf("failed\n");
558         }
559     }
560 
561     if (verbose != 0) {
562         mbedtls_printf("passed\n");
563     }
564 
565 cleanup:
566     mbedtls_sha3_free(&ctx);
567     return result;
568 }
569 
mbedtls_sha3_self_test(int verbose)570 int mbedtls_sha3_self_test(int verbose)
571 {
572     int i;
573 
574     /* SHA-3 Known Answer Tests (KAT) */
575     for (i = 0; i < 2; i++) {
576         if (0 != mbedtls_sha3_kat_test(verbose,
577                                        "SHA3-224", MBEDTLS_SHA3_224, i)) {
578             return 1;
579         }
580 
581         if (0 != mbedtls_sha3_kat_test(verbose,
582                                        "SHA3-256", MBEDTLS_SHA3_256, i)) {
583             return 1;
584         }
585 
586         if (0 != mbedtls_sha3_kat_test(verbose,
587                                        "SHA3-384", MBEDTLS_SHA3_384, i)) {
588             return 1;
589         }
590 
591         if (0 != mbedtls_sha3_kat_test(verbose,
592                                        "SHA3-512", MBEDTLS_SHA3_512, i)) {
593             return 1;
594         }
595     }
596 
597     /* SHA-3 long KAT tests */
598     if (0 != mbedtls_sha3_long_kat_test(verbose,
599                                         "SHA3-224", MBEDTLS_SHA3_224)) {
600         return 1;
601     }
602 
603     if (0 != mbedtls_sha3_long_kat_test(verbose,
604                                         "SHA3-256", MBEDTLS_SHA3_256)) {
605         return 1;
606     }
607 
608     if (0 != mbedtls_sha3_long_kat_test(verbose,
609                                         "SHA3-384", MBEDTLS_SHA3_384)) {
610         return 1;
611     }
612 
613     if (0 != mbedtls_sha3_long_kat_test(verbose,
614                                         "SHA3-512", MBEDTLS_SHA3_512)) {
615         return 1;
616     }
617 
618     if (verbose != 0) {
619         mbedtls_printf("\n");
620     }
621 
622     return 0;
623 }
624 #endif /* MBEDTLS_SELF_TEST */
625 
626 #endif /* MBEDTLS_SHA3_C */
627