1*b0563631STom Van Eyck /*
2*b0563631STom Van Eyck * FIPS-202 compliant SHA3 implementation
3*b0563631STom Van Eyck *
4*b0563631STom Van Eyck * Copyright The Mbed TLS Contributors
5*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*b0563631STom Van Eyck */
7*b0563631STom Van Eyck /*
8*b0563631STom Van Eyck * The SHA-3 Secure Hash Standard was published by NIST in 2015.
9*b0563631STom Van Eyck *
10*b0563631STom Van Eyck * https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
11*b0563631STom Van Eyck */
12*b0563631STom Van Eyck
13*b0563631STom Van Eyck #include "common.h"
14*b0563631STom Van Eyck
15*b0563631STom Van Eyck #if defined(MBEDTLS_SHA3_C)
16*b0563631STom Van Eyck
17*b0563631STom Van Eyck /*
18*b0563631STom Van Eyck * These macros select manually unrolled implementations of parts of the main permutation function.
19*b0563631STom Van Eyck *
20*b0563631STom Van Eyck * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
21*b0563631STom Van Eyck * from manually unrolling at higher optimisation levels.
22*b0563631STom Van Eyck *
23*b0563631STom Van Eyck * Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust
24*b0563631STom Van Eyck * these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and
25*b0563631STom Van Eyck * x86-64.
26*b0563631STom Van Eyck */
27*b0563631STom Van Eyck #if !defined(MBEDTLS_SHA3_THETA_UNROLL)
28*b0563631STom Van Eyck #define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names
29*b0563631STom Van Eyck #endif
30*b0563631STom Van Eyck #if !defined(MBEDTLS_SHA3_CHI_UNROLL)
31*b0563631STom Van Eyck #if defined(__OPTIMIZE_SIZE__)
32*b0563631STom Van Eyck #define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names
33*b0563631STom Van Eyck #else
34*b0563631STom Van Eyck #define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names
35*b0563631STom Van Eyck #endif
36*b0563631STom Van Eyck #endif
37*b0563631STom Van Eyck #if !defined(MBEDTLS_SHA3_PI_UNROLL)
38*b0563631STom Van Eyck #define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names
39*b0563631STom Van Eyck #endif
40*b0563631STom Van Eyck #if !defined(MBEDTLS_SHA3_RHO_UNROLL)
41*b0563631STom Van Eyck #define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names
42*b0563631STom Van Eyck #endif
43*b0563631STom Van Eyck
44*b0563631STom Van Eyck #include "mbedtls/sha3.h"
45*b0563631STom Van Eyck #include "mbedtls/platform_util.h"
46*b0563631STom Van Eyck #include "mbedtls/error.h"
47*b0563631STom Van Eyck
48*b0563631STom Van Eyck #include <string.h>
49*b0563631STom Van Eyck
50*b0563631STom Van Eyck #if defined(MBEDTLS_SELF_TEST)
51*b0563631STom Van Eyck #include "mbedtls/platform.h"
52*b0563631STom Van Eyck #endif /* MBEDTLS_SELF_TEST */
53*b0563631STom Van Eyck
54*b0563631STom Van Eyck #define XOR_BYTE 0x6
55*b0563631STom Van Eyck
56*b0563631STom Van Eyck /* Precomputed masks for the iota transform.
57*b0563631STom Van Eyck *
58*b0563631STom Van Eyck * Each round uses a 64-bit mask value. In each mask values, only
59*b0563631STom Van Eyck * bits whose position is of the form 2^k-1 can be set, thus only
60*b0563631STom Van Eyck * 7 of 64 bits of the mask need to be known for each mask value.
61*b0563631STom Van Eyck *
62*b0563631STom Van Eyck * We use a compressed encoding of the mask where bits 63, 31 and 15
63*b0563631STom Van Eyck * are moved to bits 4-6. This allows us to make each mask value
64*b0563631STom Van Eyck * 1 byte rather than 8 bytes, saving 7*24 = 168 bytes of data (with
65*b0563631STom Van Eyck * perhaps a little variation due to alignment). Decompressing this
66*b0563631STom Van Eyck * requires a little code, but much less than the savings on the table.
67*b0563631STom Van Eyck *
68*b0563631STom Van Eyck * The impact on performance depends on the platform and compiler.
69*b0563631STom Van Eyck * There's a bit more computation, but less memory bandwidth. A quick
70*b0563631STom Van Eyck * benchmark on x86_64 shows a 7% speed improvement with GCC and a
71*b0563631STom Van Eyck * 5% speed penalty with Clang, compared to the naive uint64_t[24] table.
72*b0563631STom Van Eyck * YMMV.
73*b0563631STom Van Eyck */
74*b0563631STom Van Eyck /* Helper macro to set the values of the higher bits in unused low positions */
75*b0563631STom Van Eyck #define H(b63, b31, b15) (b63 << 6 | b31 << 5 | b15 << 4)
76*b0563631STom Van Eyck static const uint8_t iota_r_packed[24] = {
77*b0563631STom Van Eyck H(0, 0, 0) | 0x01, H(0, 0, 1) | 0x82, H(1, 0, 1) | 0x8a, H(1, 1, 1) | 0x00,
78*b0563631STom Van Eyck H(0, 0, 1) | 0x8b, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x09,
79*b0563631STom Van Eyck H(0, 0, 0) | 0x8a, H(0, 0, 0) | 0x88, H(0, 1, 1) | 0x09, H(0, 1, 0) | 0x0a,
80*b0563631STom Van Eyck H(0, 1, 1) | 0x8b, H(1, 0, 0) | 0x8b, H(1, 0, 1) | 0x89, H(1, 0, 1) | 0x03,
81*b0563631STom Van Eyck H(1, 0, 1) | 0x02, H(1, 0, 0) | 0x80, H(0, 0, 1) | 0x0a, H(1, 1, 0) | 0x0a,
82*b0563631STom Van Eyck H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x80, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x08,
83*b0563631STom Van Eyck };
84*b0563631STom Van Eyck #undef H
85*b0563631STom Van Eyck
86*b0563631STom Van Eyck static const uint32_t rho[6] = {
87*b0563631STom Van Eyck 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
88*b0563631STom Van Eyck };
89*b0563631STom Van Eyck
90*b0563631STom Van Eyck static const uint32_t pi[6] = {
91*b0563631STom Van Eyck 0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916
92*b0563631STom Van Eyck };
93*b0563631STom Van Eyck
94*b0563631STom Van Eyck #define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
95*b0563631STom Van Eyck #define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
96*b0563631STom Van Eyck } while (0)
97*b0563631STom Van Eyck #define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
98*b0563631STom Van Eyck #define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
99*b0563631STom Van Eyck
100*b0563631STom Van Eyck /* The permutation function. */
keccak_f1600(mbedtls_sha3_context * ctx)101*b0563631STom Van Eyck static void keccak_f1600(mbedtls_sha3_context *ctx)
102*b0563631STom Van Eyck {
103*b0563631STom Van Eyck uint64_t lane[5];
104*b0563631STom Van Eyck uint64_t *s = ctx->state;
105*b0563631STom Van Eyck int i;
106*b0563631STom Van Eyck
107*b0563631STom Van Eyck for (int round = 0; round < 24; round++) {
108*b0563631STom Van Eyck uint64_t t;
109*b0563631STom Van Eyck
110*b0563631STom Van Eyck /* Theta */
111*b0563631STom Van Eyck #if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
112*b0563631STom Van Eyck for (i = 0; i < 5; i++) {
113*b0563631STom Van Eyck lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
114*b0563631STom Van Eyck }
115*b0563631STom Van Eyck for (i = 0; i < 5; i++) {
116*b0563631STom Van Eyck t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
117*b0563631STom Van Eyck s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
118*b0563631STom Van Eyck }
119*b0563631STom Van Eyck #else
120*b0563631STom Van Eyck lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
121*b0563631STom Van Eyck lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
122*b0563631STom Van Eyck lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
123*b0563631STom Van Eyck lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
124*b0563631STom Van Eyck lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
125*b0563631STom Van Eyck
126*b0563631STom Van Eyck t = lane[4] ^ ROTR64(lane[1], 63);
127*b0563631STom Van Eyck s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
128*b0563631STom Van Eyck
129*b0563631STom Van Eyck t = lane[0] ^ ROTR64(lane[2], 63);
130*b0563631STom Van Eyck s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
131*b0563631STom Van Eyck
132*b0563631STom Van Eyck t = lane[1] ^ ROTR64(lane[3], 63);
133*b0563631STom Van Eyck s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
134*b0563631STom Van Eyck
135*b0563631STom Van Eyck t = lane[2] ^ ROTR64(lane[4], 63);
136*b0563631STom Van Eyck s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
137*b0563631STom Van Eyck
138*b0563631STom Van Eyck t = lane[3] ^ ROTR64(lane[0], 63);
139*b0563631STom Van Eyck s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
140*b0563631STom Van Eyck #endif
141*b0563631STom Van Eyck
142*b0563631STom Van Eyck /* Rho */
143*b0563631STom Van Eyck for (i = 1; i < 25; i += 4) {
144*b0563631STom Van Eyck uint32_t r = rho[(i - 1) >> 2];
145*b0563631STom Van Eyck #if MBEDTLS_SHA3_RHO_UNROLL == 0
146*b0563631STom Van Eyck for (int j = i; j < i + 4; j++) {
147*b0563631STom Van Eyck uint8_t r8 = (uint8_t) (r >> 24);
148*b0563631STom Van Eyck r <<= 8;
149*b0563631STom Van Eyck s[j] = ROTR64(s[j], r8);
150*b0563631STom Van Eyck }
151*b0563631STom Van Eyck #else
152*b0563631STom Van Eyck s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
153*b0563631STom Van Eyck s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
154*b0563631STom Van Eyck s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
155*b0563631STom Van Eyck s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
156*b0563631STom Van Eyck #endif
157*b0563631STom Van Eyck }
158*b0563631STom Van Eyck
159*b0563631STom Van Eyck /* Pi */
160*b0563631STom Van Eyck t = s[1];
161*b0563631STom Van Eyck #if MBEDTLS_SHA3_PI_UNROLL == 0
162*b0563631STom Van Eyck for (i = 0; i < 24; i += 4) {
163*b0563631STom Van Eyck uint32_t p = pi[i >> 2];
164*b0563631STom Van Eyck for (unsigned j = 0; j < 4; j++) {
165*b0563631STom Van Eyck SWAP(s[p & 0xff], t);
166*b0563631STom Van Eyck p >>= 8;
167*b0563631STom Van Eyck }
168*b0563631STom Van Eyck }
169*b0563631STom Van Eyck #else
170*b0563631STom Van Eyck uint32_t p = pi[0];
171*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
172*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
173*b0563631STom Van Eyck p = pi[1];
174*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
175*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
176*b0563631STom Van Eyck p = pi[2];
177*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
178*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
179*b0563631STom Van Eyck p = pi[3];
180*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
181*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
182*b0563631STom Van Eyck p = pi[4];
183*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
184*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
185*b0563631STom Van Eyck p = pi[5];
186*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
187*b0563631STom Van Eyck SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
188*b0563631STom Van Eyck #endif
189*b0563631STom Van Eyck
190*b0563631STom Van Eyck /* Chi */
191*b0563631STom Van Eyck #if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names
192*b0563631STom Van Eyck for (i = 0; i <= 20; i += 5) {
193*b0563631STom Van Eyck lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2];
194*b0563631STom Van Eyck lane[3] = s[i + 3]; lane[4] = s[i + 4];
195*b0563631STom Van Eyck s[i + 0] ^= (~lane[1]) & lane[2];
196*b0563631STom Van Eyck s[i + 1] ^= (~lane[2]) & lane[3];
197*b0563631STom Van Eyck s[i + 2] ^= (~lane[3]) & lane[4];
198*b0563631STom Van Eyck s[i + 3] ^= (~lane[4]) & lane[0];
199*b0563631STom Van Eyck s[i + 4] ^= (~lane[0]) & lane[1];
200*b0563631STom Van Eyck }
201*b0563631STom Van Eyck #else
202*b0563631STom Van Eyck lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
203*b0563631STom Van Eyck s[0] ^= (~lane[1]) & lane[2];
204*b0563631STom Van Eyck s[1] ^= (~lane[2]) & lane[3];
205*b0563631STom Van Eyck s[2] ^= (~lane[3]) & lane[4];
206*b0563631STom Van Eyck s[3] ^= (~lane[4]) & lane[0];
207*b0563631STom Van Eyck s[4] ^= (~lane[0]) & lane[1];
208*b0563631STom Van Eyck
209*b0563631STom Van Eyck lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
210*b0563631STom Van Eyck s[5] ^= (~lane[1]) & lane[2];
211*b0563631STom Van Eyck s[6] ^= (~lane[2]) & lane[3];
212*b0563631STom Van Eyck s[7] ^= (~lane[3]) & lane[4];
213*b0563631STom Van Eyck s[8] ^= (~lane[4]) & lane[0];
214*b0563631STom Van Eyck s[9] ^= (~lane[0]) & lane[1];
215*b0563631STom Van Eyck
216*b0563631STom Van Eyck lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
217*b0563631STom Van Eyck s[10] ^= (~lane[1]) & lane[2];
218*b0563631STom Van Eyck s[11] ^= (~lane[2]) & lane[3];
219*b0563631STom Van Eyck s[12] ^= (~lane[3]) & lane[4];
220*b0563631STom Van Eyck s[13] ^= (~lane[4]) & lane[0];
221*b0563631STom Van Eyck s[14] ^= (~lane[0]) & lane[1];
222*b0563631STom Van Eyck
223*b0563631STom Van Eyck lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
224*b0563631STom Van Eyck s[15] ^= (~lane[1]) & lane[2];
225*b0563631STom Van Eyck s[16] ^= (~lane[2]) & lane[3];
226*b0563631STom Van Eyck s[17] ^= (~lane[3]) & lane[4];
227*b0563631STom Van Eyck s[18] ^= (~lane[4]) & lane[0];
228*b0563631STom Van Eyck s[19] ^= (~lane[0]) & lane[1];
229*b0563631STom Van Eyck
230*b0563631STom Van Eyck lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
231*b0563631STom Van Eyck s[20] ^= (~lane[1]) & lane[2];
232*b0563631STom Van Eyck s[21] ^= (~lane[2]) & lane[3];
233*b0563631STom Van Eyck s[22] ^= (~lane[3]) & lane[4];
234*b0563631STom Van Eyck s[23] ^= (~lane[4]) & lane[0];
235*b0563631STom Van Eyck s[24] ^= (~lane[0]) & lane[1];
236*b0563631STom Van Eyck #endif
237*b0563631STom Van Eyck
238*b0563631STom Van Eyck /* Iota */
239*b0563631STom Van Eyck /* Decompress the round masks (see definition of rc) */
240*b0563631STom Van Eyck s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
241*b0563631STom Van Eyck (iota_r_packed[round] & 0x20ull) << 26 |
242*b0563631STom Van Eyck (iota_r_packed[round] & 0x10ull) << 11 |
243*b0563631STom Van Eyck (iota_r_packed[round] & 0x8f));
244*b0563631STom Van Eyck }
245*b0563631STom Van Eyck }
246*b0563631STom Van Eyck
mbedtls_sha3_init(mbedtls_sha3_context * ctx)247*b0563631STom Van Eyck void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
248*b0563631STom Van Eyck {
249*b0563631STom Van Eyck memset(ctx, 0, sizeof(mbedtls_sha3_context));
250*b0563631STom Van Eyck }
251*b0563631STom Van Eyck
mbedtls_sha3_free(mbedtls_sha3_context * ctx)252*b0563631STom Van Eyck void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
253*b0563631STom Van Eyck {
254*b0563631STom Van Eyck if (ctx == NULL) {
255*b0563631STom Van Eyck return;
256*b0563631STom Van Eyck }
257*b0563631STom Van Eyck
258*b0563631STom Van Eyck mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
259*b0563631STom Van Eyck }
260*b0563631STom Van Eyck
mbedtls_sha3_clone(mbedtls_sha3_context * dst,const mbedtls_sha3_context * src)261*b0563631STom Van Eyck void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
262*b0563631STom Van Eyck const mbedtls_sha3_context *src)
263*b0563631STom Van Eyck {
264*b0563631STom Van Eyck *dst = *src;
265*b0563631STom Van Eyck }
266*b0563631STom Van Eyck
267*b0563631STom Van Eyck /*
268*b0563631STom Van Eyck * SHA-3 context setup
269*b0563631STom Van Eyck */
mbedtls_sha3_starts(mbedtls_sha3_context * ctx,mbedtls_sha3_id id)270*b0563631STom Van Eyck int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
271*b0563631STom Van Eyck {
272*b0563631STom Van Eyck switch (id) {
273*b0563631STom Van Eyck case MBEDTLS_SHA3_224:
274*b0563631STom Van Eyck ctx->olen = 224 / 8;
275*b0563631STom Van Eyck ctx->max_block_size = 1152 / 8;
276*b0563631STom Van Eyck break;
277*b0563631STom Van Eyck case MBEDTLS_SHA3_256:
278*b0563631STom Van Eyck ctx->olen = 256 / 8;
279*b0563631STom Van Eyck ctx->max_block_size = 1088 / 8;
280*b0563631STom Van Eyck break;
281*b0563631STom Van Eyck case MBEDTLS_SHA3_384:
282*b0563631STom Van Eyck ctx->olen = 384 / 8;
283*b0563631STom Van Eyck ctx->max_block_size = 832 / 8;
284*b0563631STom Van Eyck break;
285*b0563631STom Van Eyck case MBEDTLS_SHA3_512:
286*b0563631STom Van Eyck ctx->olen = 512 / 8;
287*b0563631STom Van Eyck ctx->max_block_size = 576 / 8;
288*b0563631STom Van Eyck break;
289*b0563631STom Van Eyck default:
290*b0563631STom Van Eyck return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
291*b0563631STom Van Eyck }
292*b0563631STom Van Eyck
293*b0563631STom Van Eyck memset(ctx->state, 0, sizeof(ctx->state));
294*b0563631STom Van Eyck ctx->index = 0;
295*b0563631STom Van Eyck
296*b0563631STom Van Eyck return 0;
297*b0563631STom Van Eyck }
298*b0563631STom Van Eyck
299*b0563631STom Van Eyck /*
300*b0563631STom Van Eyck * SHA-3 process buffer
301*b0563631STom Van Eyck */
mbedtls_sha3_update(mbedtls_sha3_context * ctx,const uint8_t * input,size_t ilen)302*b0563631STom Van Eyck int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
303*b0563631STom Van Eyck const uint8_t *input,
304*b0563631STom Van Eyck size_t ilen)
305*b0563631STom Van Eyck {
306*b0563631STom Van Eyck if (ilen >= 8) {
307*b0563631STom Van Eyck // 8-byte align index
308*b0563631STom Van Eyck int align_bytes = 8 - (ctx->index % 8);
309*b0563631STom Van Eyck if (align_bytes) {
310*b0563631STom Van Eyck for (; align_bytes > 0; align_bytes--) {
311*b0563631STom Van Eyck ABSORB(ctx, ctx->index, *input++);
312*b0563631STom Van Eyck ilen--;
313*b0563631STom Van Eyck ctx->index++;
314*b0563631STom Van Eyck }
315*b0563631STom Van Eyck if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
316*b0563631STom Van Eyck keccak_f1600(ctx);
317*b0563631STom Van Eyck }
318*b0563631STom Van Eyck }
319*b0563631STom Van Eyck
320*b0563631STom Van Eyck // process input in 8-byte chunks
321*b0563631STom Van Eyck while (ilen >= 8) {
322*b0563631STom Van Eyck ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
323*b0563631STom Van Eyck input += 8;
324*b0563631STom Van Eyck ilen -= 8;
325*b0563631STom Van Eyck if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
326*b0563631STom Van Eyck keccak_f1600(ctx);
327*b0563631STom Van Eyck }
328*b0563631STom Van Eyck }
329*b0563631STom Van Eyck }
330*b0563631STom Van Eyck
331*b0563631STom Van Eyck // handle remaining bytes
332*b0563631STom Van Eyck while (ilen-- > 0) {
333*b0563631STom Van Eyck ABSORB(ctx, ctx->index, *input++);
334*b0563631STom Van Eyck if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
335*b0563631STom Van Eyck keccak_f1600(ctx);
336*b0563631STom Van Eyck }
337*b0563631STom Van Eyck }
338*b0563631STom Van Eyck
339*b0563631STom Van Eyck return 0;
340*b0563631STom Van Eyck }
341*b0563631STom Van Eyck
mbedtls_sha3_finish(mbedtls_sha3_context * ctx,uint8_t * output,size_t olen)342*b0563631STom Van Eyck int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
343*b0563631STom Van Eyck uint8_t *output, size_t olen)
344*b0563631STom Van Eyck {
345*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
346*b0563631STom Van Eyck
347*b0563631STom Van Eyck /* Catch SHA-3 families, with fixed output length */
348*b0563631STom Van Eyck if (ctx->olen > 0) {
349*b0563631STom Van Eyck if (ctx->olen > olen) {
350*b0563631STom Van Eyck ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
351*b0563631STom Van Eyck goto exit;
352*b0563631STom Van Eyck }
353*b0563631STom Van Eyck olen = ctx->olen;
354*b0563631STom Van Eyck }
355*b0563631STom Van Eyck
356*b0563631STom Van Eyck ABSORB(ctx, ctx->index, XOR_BYTE);
357*b0563631STom Van Eyck ABSORB(ctx, ctx->max_block_size - 1, 0x80);
358*b0563631STom Van Eyck keccak_f1600(ctx);
359*b0563631STom Van Eyck ctx->index = 0;
360*b0563631STom Van Eyck
361*b0563631STom Van Eyck while (olen-- > 0) {
362*b0563631STom Van Eyck *output++ = SQUEEZE(ctx, ctx->index);
363*b0563631STom Van Eyck
364*b0563631STom Van Eyck if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
365*b0563631STom Van Eyck keccak_f1600(ctx);
366*b0563631STom Van Eyck }
367*b0563631STom Van Eyck }
368*b0563631STom Van Eyck
369*b0563631STom Van Eyck ret = 0;
370*b0563631STom Van Eyck
371*b0563631STom Van Eyck exit:
372*b0563631STom Van Eyck mbedtls_sha3_free(ctx);
373*b0563631STom Van Eyck return ret;
374*b0563631STom Van Eyck }
375*b0563631STom Van Eyck
376*b0563631STom Van Eyck /*
377*b0563631STom Van Eyck * output = SHA-3( input buffer )
378*b0563631STom Van Eyck */
mbedtls_sha3(mbedtls_sha3_id id,const uint8_t * input,size_t ilen,uint8_t * output,size_t olen)379*b0563631STom Van Eyck int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
380*b0563631STom Van Eyck size_t ilen, uint8_t *output, size_t olen)
381*b0563631STom Van Eyck {
382*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
383*b0563631STom Van Eyck mbedtls_sha3_context ctx;
384*b0563631STom Van Eyck
385*b0563631STom Van Eyck mbedtls_sha3_init(&ctx);
386*b0563631STom Van Eyck
387*b0563631STom Van Eyck /* Sanity checks are performed in every mbedtls_sha3_xxx() */
388*b0563631STom Van Eyck if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
389*b0563631STom Van Eyck goto exit;
390*b0563631STom Van Eyck }
391*b0563631STom Van Eyck
392*b0563631STom Van Eyck if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
393*b0563631STom Van Eyck goto exit;
394*b0563631STom Van Eyck }
395*b0563631STom Van Eyck
396*b0563631STom Van Eyck if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
397*b0563631STom Van Eyck goto exit;
398*b0563631STom Van Eyck }
399*b0563631STom Van Eyck
400*b0563631STom Van Eyck exit:
401*b0563631STom Van Eyck mbedtls_sha3_free(&ctx);
402*b0563631STom Van Eyck
403*b0563631STom Van Eyck return ret;
404*b0563631STom Van Eyck }
405*b0563631STom Van Eyck
406*b0563631STom Van Eyck /**************** Self-tests ****************/
407*b0563631STom Van Eyck
408*b0563631STom Van Eyck #if defined(MBEDTLS_SELF_TEST)
409*b0563631STom Van Eyck
410*b0563631STom Van Eyck static const unsigned char test_data[2][4] =
411*b0563631STom Van Eyck {
412*b0563631STom Van Eyck "",
413*b0563631STom Van Eyck "abc",
414*b0563631STom Van Eyck };
415*b0563631STom Van Eyck
416*b0563631STom Van Eyck static const size_t test_data_len[2] =
417*b0563631STom Van Eyck {
418*b0563631STom Van Eyck 0, /* "" */
419*b0563631STom Van Eyck 3 /* "abc" */
420*b0563631STom Van Eyck };
421*b0563631STom Van Eyck
422*b0563631STom Van Eyck static const unsigned char test_hash_sha3_224[2][28] =
423*b0563631STom Van Eyck {
424*b0563631STom Van Eyck { /* "" */
425*b0563631STom Van Eyck 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
426*b0563631STom Van Eyck 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
427*b0563631STom Van Eyck 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
428*b0563631STom Van Eyck 0x5B, 0x5A, 0x6B, 0xC7
429*b0563631STom Van Eyck },
430*b0563631STom Van Eyck { /* "abc" */
431*b0563631STom Van Eyck 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
432*b0563631STom Van Eyck 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
433*b0563631STom Van Eyck 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
434*b0563631STom Van Eyck 0x73, 0xB4, 0x6F, 0xDF
435*b0563631STom Van Eyck }
436*b0563631STom Van Eyck };
437*b0563631STom Van Eyck
438*b0563631STom Van Eyck static const unsigned char test_hash_sha3_256[2][32] =
439*b0563631STom Van Eyck {
440*b0563631STom Van Eyck { /* "" */
441*b0563631STom Van Eyck 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
442*b0563631STom Van Eyck 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
443*b0563631STom Van Eyck 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
444*b0563631STom Van Eyck 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
445*b0563631STom Van Eyck },
446*b0563631STom Van Eyck { /* "abc" */
447*b0563631STom Van Eyck 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
448*b0563631STom Van Eyck 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
449*b0563631STom Van Eyck 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
450*b0563631STom Van Eyck 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
451*b0563631STom Van Eyck }
452*b0563631STom Van Eyck };
453*b0563631STom Van Eyck
454*b0563631STom Van Eyck static const unsigned char test_hash_sha3_384[2][48] =
455*b0563631STom Van Eyck {
456*b0563631STom Van Eyck { /* "" */
457*b0563631STom Van Eyck 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
458*b0563631STom Van Eyck 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
459*b0563631STom Van Eyck 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
460*b0563631STom Van Eyck 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
461*b0563631STom Van Eyck 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
462*b0563631STom Van Eyck 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
463*b0563631STom Van Eyck },
464*b0563631STom Van Eyck { /* "abc" */
465*b0563631STom Van Eyck 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
466*b0563631STom Van Eyck 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
467*b0563631STom Van Eyck 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
468*b0563631STom Van Eyck 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
469*b0563631STom Van Eyck 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
470*b0563631STom Van Eyck 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
471*b0563631STom Van Eyck }
472*b0563631STom Van Eyck };
473*b0563631STom Van Eyck
474*b0563631STom Van Eyck static const unsigned char test_hash_sha3_512[2][64] =
475*b0563631STom Van Eyck {
476*b0563631STom Van Eyck { /* "" */
477*b0563631STom Van Eyck 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
478*b0563631STom Van Eyck 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
479*b0563631STom Van Eyck 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
480*b0563631STom Van Eyck 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
481*b0563631STom Van Eyck 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
482*b0563631STom Van Eyck 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
483*b0563631STom Van Eyck 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
484*b0563631STom Van Eyck 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
485*b0563631STom Van Eyck },
486*b0563631STom Van Eyck { /* "abc" */
487*b0563631STom Van Eyck 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
488*b0563631STom Van Eyck 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
489*b0563631STom Van Eyck 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
490*b0563631STom Van Eyck 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
491*b0563631STom Van Eyck 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
492*b0563631STom Van Eyck 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
493*b0563631STom Van Eyck 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
494*b0563631STom Van Eyck 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
495*b0563631STom Van Eyck }
496*b0563631STom Van Eyck };
497*b0563631STom Van Eyck
498*b0563631STom Van Eyck static const unsigned char long_kat_hash_sha3_224[28] =
499*b0563631STom Van Eyck {
500*b0563631STom Van Eyck 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
501*b0563631STom Van Eyck 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
502*b0563631STom Van Eyck 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
503*b0563631STom Van Eyck 0xA7, 0xFD, 0x65, 0x3C
504*b0563631STom Van Eyck };
505*b0563631STom Van Eyck
506*b0563631STom Van Eyck static const unsigned char long_kat_hash_sha3_256[32] =
507*b0563631STom Van Eyck {
508*b0563631STom Van Eyck 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
509*b0563631STom Van Eyck 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
510*b0563631STom Van Eyck 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
511*b0563631STom Van Eyck 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
512*b0563631STom Van Eyck };
513*b0563631STom Van Eyck
514*b0563631STom Van Eyck static const unsigned char long_kat_hash_sha3_384[48] =
515*b0563631STom Van Eyck {
516*b0563631STom Van Eyck 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
517*b0563631STom Van Eyck 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
518*b0563631STom Van Eyck 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
519*b0563631STom Van Eyck 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
520*b0563631STom Van Eyck 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
521*b0563631STom Van Eyck 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
522*b0563631STom Van Eyck };
523*b0563631STom Van Eyck
524*b0563631STom Van Eyck static const unsigned char long_kat_hash_sha3_512[64] =
525*b0563631STom Van Eyck {
526*b0563631STom Van Eyck 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
527*b0563631STom Van Eyck 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
528*b0563631STom Van Eyck 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
529*b0563631STom Van Eyck 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
530*b0563631STom Van Eyck 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
531*b0563631STom Van Eyck 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
532*b0563631STom Van Eyck 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
533*b0563631STom Van Eyck 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
534*b0563631STom Van Eyck };
535*b0563631STom Van Eyck
mbedtls_sha3_kat_test(int verbose,const char * type_name,mbedtls_sha3_id id,int test_num)536*b0563631STom Van Eyck static int mbedtls_sha3_kat_test(int verbose,
537*b0563631STom Van Eyck const char *type_name,
538*b0563631STom Van Eyck mbedtls_sha3_id id,
539*b0563631STom Van Eyck int test_num)
540*b0563631STom Van Eyck {
541*b0563631STom Van Eyck uint8_t hash[64];
542*b0563631STom Van Eyck int result;
543*b0563631STom Van Eyck
544*b0563631STom Van Eyck result = mbedtls_sha3(id,
545*b0563631STom Van Eyck test_data[test_num], test_data_len[test_num],
546*b0563631STom Van Eyck hash, sizeof(hash));
547*b0563631STom Van Eyck if (result != 0) {
548*b0563631STom Van Eyck if (verbose != 0) {
549*b0563631STom Van Eyck mbedtls_printf(" %s test %d error code: %d\n",
550*b0563631STom Van Eyck type_name, test_num, result);
551*b0563631STom Van Eyck }
552*b0563631STom Van Eyck
553*b0563631STom Van Eyck return result;
554*b0563631STom Van Eyck }
555*b0563631STom Van Eyck
556*b0563631STom Van Eyck switch (id) {
557*b0563631STom Van Eyck case MBEDTLS_SHA3_224:
558*b0563631STom Van Eyck result = memcmp(hash, test_hash_sha3_224[test_num], 28);
559*b0563631STom Van Eyck break;
560*b0563631STom Van Eyck case MBEDTLS_SHA3_256:
561*b0563631STom Van Eyck result = memcmp(hash, test_hash_sha3_256[test_num], 32);
562*b0563631STom Van Eyck break;
563*b0563631STom Van Eyck case MBEDTLS_SHA3_384:
564*b0563631STom Van Eyck result = memcmp(hash, test_hash_sha3_384[test_num], 48);
565*b0563631STom Van Eyck break;
566*b0563631STom Van Eyck case MBEDTLS_SHA3_512:
567*b0563631STom Van Eyck result = memcmp(hash, test_hash_sha3_512[test_num], 64);
568*b0563631STom Van Eyck break;
569*b0563631STom Van Eyck default:
570*b0563631STom Van Eyck break;
571*b0563631STom Van Eyck }
572*b0563631STom Van Eyck
573*b0563631STom Van Eyck if (0 != result) {
574*b0563631STom Van Eyck if (verbose != 0) {
575*b0563631STom Van Eyck mbedtls_printf(" %s test %d failed\n", type_name, test_num);
576*b0563631STom Van Eyck }
577*b0563631STom Van Eyck
578*b0563631STom Van Eyck return -1;
579*b0563631STom Van Eyck }
580*b0563631STom Van Eyck
581*b0563631STom Van Eyck if (verbose != 0) {
582*b0563631STom Van Eyck mbedtls_printf(" %s test %d passed\n", type_name, test_num);
583*b0563631STom Van Eyck }
584*b0563631STom Van Eyck
585*b0563631STom Van Eyck return 0;
586*b0563631STom Van Eyck }
587*b0563631STom Van Eyck
mbedtls_sha3_long_kat_test(int verbose,const char * type_name,mbedtls_sha3_id id)588*b0563631STom Van Eyck static int mbedtls_sha3_long_kat_test(int verbose,
589*b0563631STom Van Eyck const char *type_name,
590*b0563631STom Van Eyck mbedtls_sha3_id id)
591*b0563631STom Van Eyck {
592*b0563631STom Van Eyck mbedtls_sha3_context ctx;
593*b0563631STom Van Eyck unsigned char buffer[1000];
594*b0563631STom Van Eyck unsigned char hash[64];
595*b0563631STom Van Eyck int result = 0;
596*b0563631STom Van Eyck
597*b0563631STom Van Eyck memset(buffer, 'a', 1000);
598*b0563631STom Van Eyck
599*b0563631STom Van Eyck if (verbose != 0) {
600*b0563631STom Van Eyck mbedtls_printf(" %s long KAT test ", type_name);
601*b0563631STom Van Eyck }
602*b0563631STom Van Eyck
603*b0563631STom Van Eyck mbedtls_sha3_init(&ctx);
604*b0563631STom Van Eyck
605*b0563631STom Van Eyck result = mbedtls_sha3_starts(&ctx, id);
606*b0563631STom Van Eyck if (result != 0) {
607*b0563631STom Van Eyck if (verbose != 0) {
608*b0563631STom Van Eyck mbedtls_printf("setup failed\n ");
609*b0563631STom Van Eyck }
610*b0563631STom Van Eyck }
611*b0563631STom Van Eyck
612*b0563631STom Van Eyck /* Process 1,000,000 (one million) 'a' characters */
613*b0563631STom Van Eyck for (int i = 0; i < 1000; i++) {
614*b0563631STom Van Eyck result = mbedtls_sha3_update(&ctx, buffer, 1000);
615*b0563631STom Van Eyck if (result != 0) {
616*b0563631STom Van Eyck if (verbose != 0) {
617*b0563631STom Van Eyck mbedtls_printf("update error code: %i\n", result);
618*b0563631STom Van Eyck }
619*b0563631STom Van Eyck
620*b0563631STom Van Eyck goto cleanup;
621*b0563631STom Van Eyck }
622*b0563631STom Van Eyck }
623*b0563631STom Van Eyck
624*b0563631STom Van Eyck result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
625*b0563631STom Van Eyck if (result != 0) {
626*b0563631STom Van Eyck if (verbose != 0) {
627*b0563631STom Van Eyck mbedtls_printf("finish error code: %d\n", result);
628*b0563631STom Van Eyck }
629*b0563631STom Van Eyck
630*b0563631STom Van Eyck goto cleanup;
631*b0563631STom Van Eyck }
632*b0563631STom Van Eyck
633*b0563631STom Van Eyck switch (id) {
634*b0563631STom Van Eyck case MBEDTLS_SHA3_224:
635*b0563631STom Van Eyck result = memcmp(hash, long_kat_hash_sha3_224, 28);
636*b0563631STom Van Eyck break;
637*b0563631STom Van Eyck case MBEDTLS_SHA3_256:
638*b0563631STom Van Eyck result = memcmp(hash, long_kat_hash_sha3_256, 32);
639*b0563631STom Van Eyck break;
640*b0563631STom Van Eyck case MBEDTLS_SHA3_384:
641*b0563631STom Van Eyck result = memcmp(hash, long_kat_hash_sha3_384, 48);
642*b0563631STom Van Eyck break;
643*b0563631STom Van Eyck case MBEDTLS_SHA3_512:
644*b0563631STom Van Eyck result = memcmp(hash, long_kat_hash_sha3_512, 64);
645*b0563631STom Van Eyck break;
646*b0563631STom Van Eyck default:
647*b0563631STom Van Eyck break;
648*b0563631STom Van Eyck }
649*b0563631STom Van Eyck
650*b0563631STom Van Eyck if (result != 0) {
651*b0563631STom Van Eyck if (verbose != 0) {
652*b0563631STom Van Eyck mbedtls_printf("failed\n");
653*b0563631STom Van Eyck }
654*b0563631STom Van Eyck }
655*b0563631STom Van Eyck
656*b0563631STom Van Eyck if (verbose != 0) {
657*b0563631STom Van Eyck mbedtls_printf("passed\n");
658*b0563631STom Van Eyck }
659*b0563631STom Van Eyck
660*b0563631STom Van Eyck cleanup:
661*b0563631STom Van Eyck mbedtls_sha3_free(&ctx);
662*b0563631STom Van Eyck return result;
663*b0563631STom Van Eyck }
664*b0563631STom Van Eyck
mbedtls_sha3_self_test(int verbose)665*b0563631STom Van Eyck int mbedtls_sha3_self_test(int verbose)
666*b0563631STom Van Eyck {
667*b0563631STom Van Eyck int i;
668*b0563631STom Van Eyck
669*b0563631STom Van Eyck /* SHA-3 Known Answer Tests (KAT) */
670*b0563631STom Van Eyck for (i = 0; i < 2; i++) {
671*b0563631STom Van Eyck if (0 != mbedtls_sha3_kat_test(verbose,
672*b0563631STom Van Eyck "SHA3-224", MBEDTLS_SHA3_224, i)) {
673*b0563631STom Van Eyck return 1;
674*b0563631STom Van Eyck }
675*b0563631STom Van Eyck
676*b0563631STom Van Eyck if (0 != mbedtls_sha3_kat_test(verbose,
677*b0563631STom Van Eyck "SHA3-256", MBEDTLS_SHA3_256, i)) {
678*b0563631STom Van Eyck return 1;
679*b0563631STom Van Eyck }
680*b0563631STom Van Eyck
681*b0563631STom Van Eyck if (0 != mbedtls_sha3_kat_test(verbose,
682*b0563631STom Van Eyck "SHA3-384", MBEDTLS_SHA3_384, i)) {
683*b0563631STom Van Eyck return 1;
684*b0563631STom Van Eyck }
685*b0563631STom Van Eyck
686*b0563631STom Van Eyck if (0 != mbedtls_sha3_kat_test(verbose,
687*b0563631STom Van Eyck "SHA3-512", MBEDTLS_SHA3_512, i)) {
688*b0563631STom Van Eyck return 1;
689*b0563631STom Van Eyck }
690*b0563631STom Van Eyck }
691*b0563631STom Van Eyck
692*b0563631STom Van Eyck /* SHA-3 long KAT tests */
693*b0563631STom Van Eyck if (0 != mbedtls_sha3_long_kat_test(verbose,
694*b0563631STom Van Eyck "SHA3-224", MBEDTLS_SHA3_224)) {
695*b0563631STom Van Eyck return 1;
696*b0563631STom Van Eyck }
697*b0563631STom Van Eyck
698*b0563631STom Van Eyck if (0 != mbedtls_sha3_long_kat_test(verbose,
699*b0563631STom Van Eyck "SHA3-256", MBEDTLS_SHA3_256)) {
700*b0563631STom Van Eyck return 1;
701*b0563631STom Van Eyck }
702*b0563631STom Van Eyck
703*b0563631STom Van Eyck if (0 != mbedtls_sha3_long_kat_test(verbose,
704*b0563631STom Van Eyck "SHA3-384", MBEDTLS_SHA3_384)) {
705*b0563631STom Van Eyck return 1;
706*b0563631STom Van Eyck }
707*b0563631STom Van Eyck
708*b0563631STom Van Eyck if (0 != mbedtls_sha3_long_kat_test(verbose,
709*b0563631STom Van Eyck "SHA3-512", MBEDTLS_SHA3_512)) {
710*b0563631STom Van Eyck return 1;
711*b0563631STom Van Eyck }
712*b0563631STom Van Eyck
713*b0563631STom Van Eyck if (verbose != 0) {
714*b0563631STom Van Eyck mbedtls_printf("\n");
715*b0563631STom Van Eyck }
716*b0563631STom Van Eyck
717*b0563631STom Van Eyck return 0;
718*b0563631STom Van Eyck }
719*b0563631STom Van Eyck #endif /* MBEDTLS_SELF_TEST */
720*b0563631STom Van Eyck
721*b0563631STom Van Eyck #endif /* MBEDTLS_SHA3_C */
722