Coverage Report

Created: 2025-03-01 06:26

/src/mbedtls/library/sha3.c
Line
Count
Source (jump to first uncovered line)
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
0
#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
95
0
#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
96
0
} while (0)
97
0
#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
98
0
#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
99
100
/* The permutation function.  */
101
static void keccak_f1600(mbedtls_sha3_context *ctx)
102
0
{
103
0
    uint64_t lane[5];
104
0
    uint64_t *s = ctx->state;
105
0
    int i;
106
107
0
    for (int round = 0; round < 24; round++) {
108
0
        uint64_t t;
109
110
        /* Theta */
111
0
#if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
112
0
        for (i = 0; i < 5; i++) {
113
0
            lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
114
0
        }
115
0
        for (i = 0; i < 5; i++) {
116
0
            t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
117
0
            s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
118
0
        }
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
0
        for (i = 1; i < 25; i += 4) {
144
0
            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
0
            s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
153
0
            s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
154
0
            s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
155
0
            s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
156
0
#endif
157
0
        }
158
159
        /* Pi */
160
0
        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
0
        uint32_t p = pi[0];
171
0
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
172
0
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
173
0
        p = pi[1];
174
0
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
175
0
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
176
0
        p = pi[2];
177
0
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
178
0
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
179
0
        p = pi[3];
180
0
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
181
0
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
182
0
        p = pi[4];
183
0
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
184
0
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
185
0
        p = pi[5];
186
0
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
187
0
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
188
0
#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
0
        lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
203
0
        s[0] ^= (~lane[1]) & lane[2];
204
0
        s[1] ^= (~lane[2]) & lane[3];
205
0
        s[2] ^= (~lane[3]) & lane[4];
206
0
        s[3] ^= (~lane[4]) & lane[0];
207
0
        s[4] ^= (~lane[0]) & lane[1];
208
209
0
        lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
210
0
        s[5] ^= (~lane[1]) & lane[2];
211
0
        s[6] ^= (~lane[2]) & lane[3];
212
0
        s[7] ^= (~lane[3]) & lane[4];
213
0
        s[8] ^= (~lane[4]) & lane[0];
214
0
        s[9] ^= (~lane[0]) & lane[1];
215
216
0
        lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
217
0
        s[10] ^= (~lane[1]) & lane[2];
218
0
        s[11] ^= (~lane[2]) & lane[3];
219
0
        s[12] ^= (~lane[3]) & lane[4];
220
0
        s[13] ^= (~lane[4]) & lane[0];
221
0
        s[14] ^= (~lane[0]) & lane[1];
222
223
0
        lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
224
0
        s[15] ^= (~lane[1]) & lane[2];
225
0
        s[16] ^= (~lane[2]) & lane[3];
226
0
        s[17] ^= (~lane[3]) & lane[4];
227
0
        s[18] ^= (~lane[4]) & lane[0];
228
0
        s[19] ^= (~lane[0]) & lane[1];
229
230
0
        lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
231
0
        s[20] ^= (~lane[1]) & lane[2];
232
0
        s[21] ^= (~lane[2]) & lane[3];
233
0
        s[22] ^= (~lane[3]) & lane[4];
234
0
        s[23] ^= (~lane[4]) & lane[0];
235
0
        s[24] ^= (~lane[0]) & lane[1];
236
0
#endif
237
238
        /* Iota */
239
        /* Decompress the round masks (see definition of rc) */
240
0
        s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
241
0
                 (iota_r_packed[round] & 0x20ull) << 26 |
242
0
                 (iota_r_packed[round] & 0x10ull) << 11 |
243
0
                 (iota_r_packed[round] & 0x8f));
244
0
    }
245
0
}
246
247
void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
248
0
{
249
0
    memset(ctx, 0, sizeof(mbedtls_sha3_context));
250
0
}
251
252
void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
253
0
{
254
0
    if (ctx == NULL) {
255
0
        return;
256
0
    }
257
258
0
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
259
0
}
260
261
void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
262
                        const mbedtls_sha3_context *src)
263
0
{
264
0
    *dst = *src;
265
0
}
266
267
/*
268
 * SHA-3 context setup
269
 */
270
int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
271
0
{
272
0
    switch (id) {
273
0
        case MBEDTLS_SHA3_224:
274
0
            ctx->olen = 224 / 8;
275
0
            ctx->max_block_size = 1152 / 8;
276
0
            break;
277
0
        case MBEDTLS_SHA3_256:
278
0
            ctx->olen = 256 / 8;
279
0
            ctx->max_block_size = 1088 / 8;
280
0
            break;
281
0
        case MBEDTLS_SHA3_384:
282
0
            ctx->olen = 384 / 8;
283
0
            ctx->max_block_size = 832 / 8;
284
0
            break;
285
0
        case MBEDTLS_SHA3_512:
286
0
            ctx->olen = 512 / 8;
287
0
            ctx->max_block_size = 576 / 8;
288
0
            break;
289
0
        default:
290
0
            return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
291
0
    }
292
293
0
    memset(ctx->state, 0, sizeof(ctx->state));
294
0
    ctx->index = 0;
295
296
0
    return 0;
297
0
}
298
299
/*
300
 * SHA-3 process buffer
301
 */
302
int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
303
                        const uint8_t *input,
304
                        size_t ilen)
305
0
{
306
0
    if (ilen >= 8) {
307
        // 8-byte align index
308
0
        int align_bytes = 8 - (ctx->index % 8);
309
0
        if (align_bytes) {
310
0
            for (; align_bytes > 0; align_bytes--) {
311
0
                ABSORB(ctx, ctx->index, *input++);
312
0
                ilen--;
313
0
                ctx->index++;
314
0
            }
315
0
            if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
316
0
                keccak_f1600(ctx);
317
0
            }
318
0
        }
319
320
        // process input in 8-byte chunks
321
0
        while (ilen >= 8) {
322
0
            ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
323
0
            input += 8;
324
0
            ilen -= 8;
325
0
            if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
326
0
                keccak_f1600(ctx);
327
0
            }
328
0
        }
329
0
    }
330
331
    // handle remaining bytes
332
0
    while (ilen-- > 0) {
333
0
        ABSORB(ctx, ctx->index, *input++);
334
0
        if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
335
0
            keccak_f1600(ctx);
336
0
        }
337
0
    }
338
339
0
    return 0;
340
0
}
341
342
int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
343
                        uint8_t *output, size_t olen)
344
0
{
345
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
346
347
    /* Catch SHA-3 families, with fixed output length */
348
0
    if (ctx->olen > 0) {
349
0
        if (ctx->olen > olen) {
350
0
            ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
351
0
            goto exit;
352
0
        }
353
0
        olen = ctx->olen;
354
0
    }
355
356
0
    ABSORB(ctx, ctx->index, XOR_BYTE);
357
0
    ABSORB(ctx, ctx->max_block_size - 1, 0x80);
358
0
    keccak_f1600(ctx);
359
0
    ctx->index = 0;
360
361
0
    while (olen-- > 0) {
362
0
        *output++ = SQUEEZE(ctx, ctx->index);
363
364
0
        if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
365
0
            keccak_f1600(ctx);
366
0
        }
367
0
    }
368
369
0
    ret = 0;
370
371
0
exit:
372
0
    mbedtls_sha3_free(ctx);
373
0
    return ret;
374
0
}
375
376
/*
377
 * output = SHA-3( input buffer )
378
 */
379
int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
380
                 size_t ilen, uint8_t *output, size_t olen)
381
0
{
382
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
383
0
    mbedtls_sha3_context ctx;
384
385
0
    mbedtls_sha3_init(&ctx);
386
387
    /* Sanity checks are performed in every mbedtls_sha3_xxx() */
388
0
    if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
389
0
        goto exit;
390
0
    }
391
392
0
    if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
393
0
        goto exit;
394
0
    }
395
396
0
    if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
397
0
        goto exit;
398
0
    }
399
400
0
exit:
401
0
    mbedtls_sha3_free(&ctx);
402
403
0
    return ret;
404
0
}
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
536
static int mbedtls_sha3_kat_test(int verbose,
537
                                 const char *type_name,
538
                                 mbedtls_sha3_id id,
539
                                 int test_num)
540
0
{
541
0
    uint8_t hash[64];
542
0
    int result;
543
544
0
    result = mbedtls_sha3(id,
545
0
                          test_data[test_num], test_data_len[test_num],
546
0
                          hash, sizeof(hash));
547
0
    if (result != 0) {
548
0
        if (verbose != 0) {
549
0
            mbedtls_printf("  %s test %d error code: %d\n",
550
0
                           type_name, test_num, result);
551
0
        }
552
553
0
        return result;
554
0
    }
555
556
0
    switch (id) {
557
0
        case MBEDTLS_SHA3_224:
558
0
            result = memcmp(hash, test_hash_sha3_224[test_num], 28);
559
0
            break;
560
0
        case MBEDTLS_SHA3_256:
561
0
            result = memcmp(hash, test_hash_sha3_256[test_num], 32);
562
0
            break;
563
0
        case MBEDTLS_SHA3_384:
564
0
            result = memcmp(hash, test_hash_sha3_384[test_num], 48);
565
0
            break;
566
0
        case MBEDTLS_SHA3_512:
567
0
            result = memcmp(hash, test_hash_sha3_512[test_num], 64);
568
0
            break;
569
0
        default:
570
0
            break;
571
0
    }
572
573
0
    if (0 != result) {
574
0
        if (verbose != 0) {
575
0
            mbedtls_printf("  %s test %d failed\n", type_name, test_num);
576
0
        }
577
578
0
        return -1;
579
0
    }
580
581
0
    if (verbose != 0) {
582
0
        mbedtls_printf("  %s test %d passed\n", type_name, test_num);
583
0
    }
584
585
0
    return 0;
586
0
}
587
588
static int mbedtls_sha3_long_kat_test(int verbose,
589
                                      const char *type_name,
590
                                      mbedtls_sha3_id id)
591
0
{
592
0
    mbedtls_sha3_context ctx;
593
0
    unsigned char buffer[1000];
594
0
    unsigned char hash[64];
595
0
    int result = 0;
596
597
0
    memset(buffer, 'a', 1000);
598
599
0
    if (verbose != 0) {
600
0
        mbedtls_printf("  %s long KAT test ", type_name);
601
0
    }
602
603
0
    mbedtls_sha3_init(&ctx);
604
605
0
    result = mbedtls_sha3_starts(&ctx, id);
606
0
    if (result != 0) {
607
0
        if (verbose != 0) {
608
0
            mbedtls_printf("setup failed\n ");
609
0
        }
610
0
    }
611
612
    /* Process 1,000,000 (one million) 'a' characters */
613
0
    for (int i = 0; i < 1000; i++) {
614
0
        result = mbedtls_sha3_update(&ctx, buffer, 1000);
615
0
        if (result != 0) {
616
0
            if (verbose != 0) {
617
0
                mbedtls_printf("update error code: %i\n", result);
618
0
            }
619
620
0
            goto cleanup;
621
0
        }
622
0
    }
623
624
0
    result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
625
0
    if (result != 0) {
626
0
        if (verbose != 0) {
627
0
            mbedtls_printf("finish error code: %d\n", result);
628
0
        }
629
630
0
        goto cleanup;
631
0
    }
632
633
0
    switch (id) {
634
0
        case MBEDTLS_SHA3_224:
635
0
            result = memcmp(hash, long_kat_hash_sha3_224, 28);
636
0
            break;
637
0
        case MBEDTLS_SHA3_256:
638
0
            result = memcmp(hash, long_kat_hash_sha3_256, 32);
639
0
            break;
640
0
        case MBEDTLS_SHA3_384:
641
0
            result = memcmp(hash, long_kat_hash_sha3_384, 48);
642
0
            break;
643
0
        case MBEDTLS_SHA3_512:
644
0
            result = memcmp(hash, long_kat_hash_sha3_512, 64);
645
0
            break;
646
0
        default:
647
0
            break;
648
0
    }
649
650
0
    if (result != 0) {
651
0
        if (verbose != 0) {
652
0
            mbedtls_printf("failed\n");
653
0
        }
654
0
    }
655
656
0
    if (verbose != 0) {
657
0
        mbedtls_printf("passed\n");
658
0
    }
659
660
0
cleanup:
661
0
    mbedtls_sha3_free(&ctx);
662
0
    return result;
663
0
}
664
665
int mbedtls_sha3_self_test(int verbose)
666
0
{
667
0
    int i;
668
669
    /* SHA-3 Known Answer Tests (KAT) */
670
0
    for (i = 0; i < 2; i++) {
671
0
        if (0 != mbedtls_sha3_kat_test(verbose,
672
0
                                       "SHA3-224", MBEDTLS_SHA3_224, i)) {
673
0
            return 1;
674
0
        }
675
676
0
        if (0 != mbedtls_sha3_kat_test(verbose,
677
0
                                       "SHA3-256", MBEDTLS_SHA3_256, i)) {
678
0
            return 1;
679
0
        }
680
681
0
        if (0 != mbedtls_sha3_kat_test(verbose,
682
0
                                       "SHA3-384", MBEDTLS_SHA3_384, i)) {
683
0
            return 1;
684
0
        }
685
686
0
        if (0 != mbedtls_sha3_kat_test(verbose,
687
0
                                       "SHA3-512", MBEDTLS_SHA3_512, i)) {
688
0
            return 1;
689
0
        }
690
0
    }
691
692
    /* SHA-3 long KAT tests */
693
0
    if (0 != mbedtls_sha3_long_kat_test(verbose,
694
0
                                        "SHA3-224", MBEDTLS_SHA3_224)) {
695
0
        return 1;
696
0
    }
697
698
0
    if (0 != mbedtls_sha3_long_kat_test(verbose,
699
0
                                        "SHA3-256", MBEDTLS_SHA3_256)) {
700
0
        return 1;
701
0
    }
702
703
0
    if (0 != mbedtls_sha3_long_kat_test(verbose,
704
0
                                        "SHA3-384", MBEDTLS_SHA3_384)) {
705
0
        return 1;
706
0
    }
707
708
0
    if (0 != mbedtls_sha3_long_kat_test(verbose,
709
0
                                        "SHA3-512", MBEDTLS_SHA3_512)) {
710
0
        return 1;
711
0
    }
712
713
0
    if (verbose != 0) {
714
0
        mbedtls_printf("\n");
715
0
    }
716
717
0
    return 0;
718
0
}
719
#endif /* MBEDTLS_SELF_TEST */
720
721
#endif /* MBEDTLS_SHA3_C */