xref: /third_party/mbedtls/library/sha3.c (revision a8e1175b)
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)
76static 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
86static const uint32_t rho[6] = {
87    0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
88};
89
90static 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.  */
101static 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
247void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
248{
249    memset(ctx, 0, sizeof(mbedtls_sha3_context));
250}
251
252void 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
261void 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 */
270int 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 */
302int 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
342int 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
371exit:
372    mbedtls_sha3_free(ctx);
373    return ret;
374}
375
376/*
377 * output = SHA-3( input buffer )
378 */
379int 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
400exit:
401    mbedtls_sha3_free(&ctx);
402
403    return ret;
404}
405
406/**************** Self-tests ****************/
407
408#if defined(MBEDTLS_SELF_TEST)
409
410static const unsigned char test_data[2][4] =
411{
412    "",
413    "abc",
414};
415
416static const size_t test_data_len[2] =
417{
418    0, /* "" */
419    3  /* "abc" */
420};
421
422static 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
438static 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
454static 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
474static 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
498static 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
506static 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
514static 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
524static 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
536static 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
588static 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
660cleanup:
661    mbedtls_sha3_free(&ctx);
662    return result;
663}
664
665int 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