Coverage Report

Created: 2024-11-21 07:03

/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
113M
#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
95
4.50M
#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
96
2.27M
} while (0)
97
30.2k
#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
98
93.9M
#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
163k
{
103
163k
    uint64_t lane[5];
104
163k
    uint64_t *s = ctx->state;
105
163k
    int i;
106
107
4.07M
    for (int round = 0; round < 24; round++) {
108
3.91M
        uint64_t t;
109
110
        /* Theta */
111
3.91M
#if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
112
23.4M
        for (i = 0; i < 5; i++) {
113
19.5M
            lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
114
19.5M
        }
115
23.4M
        for (i = 0; i < 5; i++) {
116
19.5M
            t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
117
19.5M
            s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
118
19.5M
        }
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
27.4M
        for (i = 1; i < 25; i += 4) {
144
23.4M
            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
23.4M
            s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
153
23.4M
            s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
154
23.4M
            s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
155
23.4M
            s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
156
23.4M
#endif
157
23.4M
        }
158
159
        /* Pi */
160
3.91M
        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
3.91M
        uint32_t p = pi[0];
171
3.91M
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
172
3.91M
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
173
3.91M
        p = pi[1];
174
3.91M
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
175
3.91M
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
176
3.91M
        p = pi[2];
177
3.91M
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
178
3.91M
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
179
3.91M
        p = pi[3];
180
3.91M
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
181
3.91M
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
182
3.91M
        p = pi[4];
183
3.91M
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
184
3.91M
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
185
3.91M
        p = pi[5];
186
3.91M
        SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
187
3.91M
        SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
188
3.91M
#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
3.91M
        lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
203
3.91M
        s[0] ^= (~lane[1]) & lane[2];
204
3.91M
        s[1] ^= (~lane[2]) & lane[3];
205
3.91M
        s[2] ^= (~lane[3]) & lane[4];
206
3.91M
        s[3] ^= (~lane[4]) & lane[0];
207
3.91M
        s[4] ^= (~lane[0]) & lane[1];
208
209
3.91M
        lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
210
3.91M
        s[5] ^= (~lane[1]) & lane[2];
211
3.91M
        s[6] ^= (~lane[2]) & lane[3];
212
3.91M
        s[7] ^= (~lane[3]) & lane[4];
213
3.91M
        s[8] ^= (~lane[4]) & lane[0];
214
3.91M
        s[9] ^= (~lane[0]) & lane[1];
215
216
3.91M
        lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
217
3.91M
        s[10] ^= (~lane[1]) & lane[2];
218
3.91M
        s[11] ^= (~lane[2]) & lane[3];
219
3.91M
        s[12] ^= (~lane[3]) & lane[4];
220
3.91M
        s[13] ^= (~lane[4]) & lane[0];
221
3.91M
        s[14] ^= (~lane[0]) & lane[1];
222
223
3.91M
        lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
224
3.91M
        s[15] ^= (~lane[1]) & lane[2];
225
3.91M
        s[16] ^= (~lane[2]) & lane[3];
226
3.91M
        s[17] ^= (~lane[3]) & lane[4];
227
3.91M
        s[18] ^= (~lane[4]) & lane[0];
228
3.91M
        s[19] ^= (~lane[0]) & lane[1];
229
230
3.91M
        lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
231
3.91M
        s[20] ^= (~lane[1]) & lane[2];
232
3.91M
        s[21] ^= (~lane[2]) & lane[3];
233
3.91M
        s[22] ^= (~lane[3]) & lane[4];
234
3.91M
        s[23] ^= (~lane[4]) & lane[0];
235
3.91M
        s[24] ^= (~lane[0]) & lane[1];
236
3.91M
#endif
237
238
        /* Iota */
239
        /* Decompress the round masks (see definition of rc) */
240
3.91M
        s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
241
3.91M
                 (iota_r_packed[round] & 0x20ull) << 26 |
242
3.91M
                 (iota_r_packed[round] & 0x10ull) << 11 |
243
3.91M
                 (iota_r_packed[round] & 0x8f));
244
3.91M
    }
245
163k
}
246
247
void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
248
695
{
249
695
    memset(ctx, 0, sizeof(mbedtls_sha3_context));
250
695
}
251
252
void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
253
1.37k
{
254
1.37k
    if (ctx == NULL) {
255
0
        return;
256
0
    }
257
258
1.37k
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
259
1.37k
}
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
695
{
272
695
    switch (id) {
273
144
        case MBEDTLS_SHA3_224:
274
144
            ctx->olen = 224 / 8;
275
144
            ctx->max_block_size = 1152 / 8;
276
144
            break;
277
182
        case MBEDTLS_SHA3_256:
278
182
            ctx->olen = 256 / 8;
279
182
            ctx->max_block_size = 1088 / 8;
280
182
            break;
281
175
        case MBEDTLS_SHA3_384:
282
175
            ctx->olen = 384 / 8;
283
175
            ctx->max_block_size = 832 / 8;
284
175
            break;
285
194
        case MBEDTLS_SHA3_512:
286
194
            ctx->olen = 512 / 8;
287
194
            ctx->max_block_size = 576 / 8;
288
194
            break;
289
0
        default:
290
0
            return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
291
695
    }
292
293
695
    memset(ctx->state, 0, sizeof(ctx->state));
294
695
    ctx->index = 0;
295
296
695
    return 0;
297
695
}
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
2.81k
{
306
2.81k
    if (ilen >= 8) {
307
        // 8-byte align index
308
2.12k
        int align_bytes = 8 - (ctx->index % 8);
309
2.12k
        if (align_bytes) {
310
15.0k
            for (; align_bytes > 0; align_bytes--) {
311
12.8k
                ABSORB(ctx, ctx->index, *input++);
312
12.8k
                ilen--;
313
12.8k
                ctx->index++;
314
12.8k
            }
315
2.12k
            if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
316
102
                keccak_f1600(ctx);
317
102
            }
318
2.12k
        }
319
320
        // process input in 8-byte chunks
321
2.25M
        while (ilen >= 8) {
322
2.25M
            ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
323
2.25M
            input += 8;
324
2.25M
            ilen -= 8;
325
2.25M
            if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
326
162k
                keccak_f1600(ctx);
327
162k
            }
328
2.25M
        }
329
2.12k
    }
330
331
    // handle remaining bytes
332
10.4k
    while (ilen-- > 0) {
333
7.59k
        ABSORB(ctx, ctx->index, *input++);
334
7.59k
        if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
335
11
            keccak_f1600(ctx);
336
11
        }
337
7.59k
    }
338
339
2.81k
    return 0;
340
2.81k
}
341
342
int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
343
                        uint8_t *output, size_t olen)
344
683
{
345
683
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
346
347
    /* Catch SHA-3 families, with fixed output length */
348
683
    if (ctx->olen > 0) {
349
683
        if (ctx->olen > olen) {
350
0
            ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
351
0
            goto exit;
352
0
        }
353
683
        olen = ctx->olen;
354
683
    }
355
356
683
    ABSORB(ctx, ctx->index, XOR_BYTE);
357
683
    ABSORB(ctx, ctx->max_block_size - 1, 0x80);
358
683
    keccak_f1600(ctx);
359
683
    ctx->index = 0;
360
361
30.8k
    while (olen-- > 0) {
362
30.2k
        *output++ = SQUEEZE(ctx, ctx->index);
363
364
30.2k
        if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
365
0
            keccak_f1600(ctx);
366
0
        }
367
30.2k
    }
368
369
683
    ret = 0;
370
371
683
exit:
372
683
    mbedtls_sha3_free(ctx);
373
683
    return ret;
374
683
}
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 */