1*62c56f98SSadaf Ebrahimi /**
2*62c56f98SSadaf Ebrahimi * \file chacha20.c
3*62c56f98SSadaf Ebrahimi *
4*62c56f98SSadaf Ebrahimi * \brief ChaCha20 cipher.
5*62c56f98SSadaf Ebrahimi *
6*62c56f98SSadaf Ebrahimi * \author Daniel King <[email protected]>
7*62c56f98SSadaf Ebrahimi *
8*62c56f98SSadaf Ebrahimi * Copyright The Mbed TLS Contributors
9*62c56f98SSadaf Ebrahimi * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
10*62c56f98SSadaf Ebrahimi */
11*62c56f98SSadaf Ebrahimi
12*62c56f98SSadaf Ebrahimi #include "common.h"
13*62c56f98SSadaf Ebrahimi
14*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_CHACHA20_C)
15*62c56f98SSadaf Ebrahimi
16*62c56f98SSadaf Ebrahimi #include "mbedtls/chacha20.h"
17*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_util.h"
18*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
19*62c56f98SSadaf Ebrahimi
20*62c56f98SSadaf Ebrahimi #include <stddef.h>
21*62c56f98SSadaf Ebrahimi #include <string.h>
22*62c56f98SSadaf Ebrahimi
23*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
24*62c56f98SSadaf Ebrahimi
25*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_CHACHA20_ALT)
26*62c56f98SSadaf Ebrahimi
27*62c56f98SSadaf Ebrahimi #define ROTL32(value, amount) \
28*62c56f98SSadaf Ebrahimi ((uint32_t) ((value) << (amount)) | ((value) >> (32 - (amount))))
29*62c56f98SSadaf Ebrahimi
30*62c56f98SSadaf Ebrahimi #define CHACHA20_CTR_INDEX (12U)
31*62c56f98SSadaf Ebrahimi
32*62c56f98SSadaf Ebrahimi #define CHACHA20_BLOCK_SIZE_BYTES (4U * 16U)
33*62c56f98SSadaf Ebrahimi
34*62c56f98SSadaf Ebrahimi /**
35*62c56f98SSadaf Ebrahimi * \brief ChaCha20 quarter round operation.
36*62c56f98SSadaf Ebrahimi *
37*62c56f98SSadaf Ebrahimi * The quarter round is defined as follows (from RFC 7539):
38*62c56f98SSadaf Ebrahimi * 1. a += b; d ^= a; d <<<= 16;
39*62c56f98SSadaf Ebrahimi * 2. c += d; b ^= c; b <<<= 12;
40*62c56f98SSadaf Ebrahimi * 3. a += b; d ^= a; d <<<= 8;
41*62c56f98SSadaf Ebrahimi * 4. c += d; b ^= c; b <<<= 7;
42*62c56f98SSadaf Ebrahimi *
43*62c56f98SSadaf Ebrahimi * \param state ChaCha20 state to modify.
44*62c56f98SSadaf Ebrahimi * \param a The index of 'a' in the state.
45*62c56f98SSadaf Ebrahimi * \param b The index of 'b' in the state.
46*62c56f98SSadaf Ebrahimi * \param c The index of 'c' in the state.
47*62c56f98SSadaf Ebrahimi * \param d The index of 'd' in the state.
48*62c56f98SSadaf Ebrahimi */
chacha20_quarter_round(uint32_t state[16],size_t a,size_t b,size_t c,size_t d)49*62c56f98SSadaf Ebrahimi static inline void chacha20_quarter_round(uint32_t state[16],
50*62c56f98SSadaf Ebrahimi size_t a,
51*62c56f98SSadaf Ebrahimi size_t b,
52*62c56f98SSadaf Ebrahimi size_t c,
53*62c56f98SSadaf Ebrahimi size_t d)
54*62c56f98SSadaf Ebrahimi {
55*62c56f98SSadaf Ebrahimi /* a += b; d ^= a; d <<<= 16; */
56*62c56f98SSadaf Ebrahimi state[a] += state[b];
57*62c56f98SSadaf Ebrahimi state[d] ^= state[a];
58*62c56f98SSadaf Ebrahimi state[d] = ROTL32(state[d], 16);
59*62c56f98SSadaf Ebrahimi
60*62c56f98SSadaf Ebrahimi /* c += d; b ^= c; b <<<= 12 */
61*62c56f98SSadaf Ebrahimi state[c] += state[d];
62*62c56f98SSadaf Ebrahimi state[b] ^= state[c];
63*62c56f98SSadaf Ebrahimi state[b] = ROTL32(state[b], 12);
64*62c56f98SSadaf Ebrahimi
65*62c56f98SSadaf Ebrahimi /* a += b; d ^= a; d <<<= 8; */
66*62c56f98SSadaf Ebrahimi state[a] += state[b];
67*62c56f98SSadaf Ebrahimi state[d] ^= state[a];
68*62c56f98SSadaf Ebrahimi state[d] = ROTL32(state[d], 8);
69*62c56f98SSadaf Ebrahimi
70*62c56f98SSadaf Ebrahimi /* c += d; b ^= c; b <<<= 7; */
71*62c56f98SSadaf Ebrahimi state[c] += state[d];
72*62c56f98SSadaf Ebrahimi state[b] ^= state[c];
73*62c56f98SSadaf Ebrahimi state[b] = ROTL32(state[b], 7);
74*62c56f98SSadaf Ebrahimi }
75*62c56f98SSadaf Ebrahimi
76*62c56f98SSadaf Ebrahimi /**
77*62c56f98SSadaf Ebrahimi * \brief Perform the ChaCha20 inner block operation.
78*62c56f98SSadaf Ebrahimi *
79*62c56f98SSadaf Ebrahimi * This function performs two rounds: the column round and the
80*62c56f98SSadaf Ebrahimi * diagonal round.
81*62c56f98SSadaf Ebrahimi *
82*62c56f98SSadaf Ebrahimi * \param state The ChaCha20 state to update.
83*62c56f98SSadaf Ebrahimi */
chacha20_inner_block(uint32_t state[16])84*62c56f98SSadaf Ebrahimi static void chacha20_inner_block(uint32_t state[16])
85*62c56f98SSadaf Ebrahimi {
86*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 0, 4, 8, 12);
87*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 1, 5, 9, 13);
88*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 2, 6, 10, 14);
89*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 3, 7, 11, 15);
90*62c56f98SSadaf Ebrahimi
91*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 0, 5, 10, 15);
92*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 1, 6, 11, 12);
93*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 2, 7, 8, 13);
94*62c56f98SSadaf Ebrahimi chacha20_quarter_round(state, 3, 4, 9, 14);
95*62c56f98SSadaf Ebrahimi }
96*62c56f98SSadaf Ebrahimi
97*62c56f98SSadaf Ebrahimi /**
98*62c56f98SSadaf Ebrahimi * \brief Generates a keystream block.
99*62c56f98SSadaf Ebrahimi *
100*62c56f98SSadaf Ebrahimi * \param initial_state The initial ChaCha20 state (key, nonce, counter).
101*62c56f98SSadaf Ebrahimi * \param keystream Generated keystream bytes are written to this buffer.
102*62c56f98SSadaf Ebrahimi */
chacha20_block(const uint32_t initial_state[16],unsigned char keystream[64])103*62c56f98SSadaf Ebrahimi static void chacha20_block(const uint32_t initial_state[16],
104*62c56f98SSadaf Ebrahimi unsigned char keystream[64])
105*62c56f98SSadaf Ebrahimi {
106*62c56f98SSadaf Ebrahimi uint32_t working_state[16];
107*62c56f98SSadaf Ebrahimi size_t i;
108*62c56f98SSadaf Ebrahimi
109*62c56f98SSadaf Ebrahimi memcpy(working_state,
110*62c56f98SSadaf Ebrahimi initial_state,
111*62c56f98SSadaf Ebrahimi CHACHA20_BLOCK_SIZE_BYTES);
112*62c56f98SSadaf Ebrahimi
113*62c56f98SSadaf Ebrahimi for (i = 0U; i < 10U; i++) {
114*62c56f98SSadaf Ebrahimi chacha20_inner_block(working_state);
115*62c56f98SSadaf Ebrahimi }
116*62c56f98SSadaf Ebrahimi
117*62c56f98SSadaf Ebrahimi working_state[0] += initial_state[0];
118*62c56f98SSadaf Ebrahimi working_state[1] += initial_state[1];
119*62c56f98SSadaf Ebrahimi working_state[2] += initial_state[2];
120*62c56f98SSadaf Ebrahimi working_state[3] += initial_state[3];
121*62c56f98SSadaf Ebrahimi working_state[4] += initial_state[4];
122*62c56f98SSadaf Ebrahimi working_state[5] += initial_state[5];
123*62c56f98SSadaf Ebrahimi working_state[6] += initial_state[6];
124*62c56f98SSadaf Ebrahimi working_state[7] += initial_state[7];
125*62c56f98SSadaf Ebrahimi working_state[8] += initial_state[8];
126*62c56f98SSadaf Ebrahimi working_state[9] += initial_state[9];
127*62c56f98SSadaf Ebrahimi working_state[10] += initial_state[10];
128*62c56f98SSadaf Ebrahimi working_state[11] += initial_state[11];
129*62c56f98SSadaf Ebrahimi working_state[12] += initial_state[12];
130*62c56f98SSadaf Ebrahimi working_state[13] += initial_state[13];
131*62c56f98SSadaf Ebrahimi working_state[14] += initial_state[14];
132*62c56f98SSadaf Ebrahimi working_state[15] += initial_state[15];
133*62c56f98SSadaf Ebrahimi
134*62c56f98SSadaf Ebrahimi for (i = 0U; i < 16; i++) {
135*62c56f98SSadaf Ebrahimi size_t offset = i * 4U;
136*62c56f98SSadaf Ebrahimi
137*62c56f98SSadaf Ebrahimi MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
138*62c56f98SSadaf Ebrahimi }
139*62c56f98SSadaf Ebrahimi
140*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(working_state, sizeof(working_state));
141*62c56f98SSadaf Ebrahimi }
142*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_init(mbedtls_chacha20_context * ctx)143*62c56f98SSadaf Ebrahimi void mbedtls_chacha20_init(mbedtls_chacha20_context *ctx)
144*62c56f98SSadaf Ebrahimi {
145*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(ctx->state, sizeof(ctx->state));
146*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(ctx->keystream8, sizeof(ctx->keystream8));
147*62c56f98SSadaf Ebrahimi
148*62c56f98SSadaf Ebrahimi /* Initially, there's no keystream bytes available */
149*62c56f98SSadaf Ebrahimi ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
150*62c56f98SSadaf Ebrahimi }
151*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_free(mbedtls_chacha20_context * ctx)152*62c56f98SSadaf Ebrahimi void mbedtls_chacha20_free(mbedtls_chacha20_context *ctx)
153*62c56f98SSadaf Ebrahimi {
154*62c56f98SSadaf Ebrahimi if (ctx != NULL) {
155*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(ctx, sizeof(mbedtls_chacha20_context));
156*62c56f98SSadaf Ebrahimi }
157*62c56f98SSadaf Ebrahimi }
158*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_setkey(mbedtls_chacha20_context * ctx,const unsigned char key[32])159*62c56f98SSadaf Ebrahimi int mbedtls_chacha20_setkey(mbedtls_chacha20_context *ctx,
160*62c56f98SSadaf Ebrahimi const unsigned char key[32])
161*62c56f98SSadaf Ebrahimi {
162*62c56f98SSadaf Ebrahimi /* ChaCha20 constants - the string "expand 32-byte k" */
163*62c56f98SSadaf Ebrahimi ctx->state[0] = 0x61707865;
164*62c56f98SSadaf Ebrahimi ctx->state[1] = 0x3320646e;
165*62c56f98SSadaf Ebrahimi ctx->state[2] = 0x79622d32;
166*62c56f98SSadaf Ebrahimi ctx->state[3] = 0x6b206574;
167*62c56f98SSadaf Ebrahimi
168*62c56f98SSadaf Ebrahimi /* Set key */
169*62c56f98SSadaf Ebrahimi ctx->state[4] = MBEDTLS_GET_UINT32_LE(key, 0);
170*62c56f98SSadaf Ebrahimi ctx->state[5] = MBEDTLS_GET_UINT32_LE(key, 4);
171*62c56f98SSadaf Ebrahimi ctx->state[6] = MBEDTLS_GET_UINT32_LE(key, 8);
172*62c56f98SSadaf Ebrahimi ctx->state[7] = MBEDTLS_GET_UINT32_LE(key, 12);
173*62c56f98SSadaf Ebrahimi ctx->state[8] = MBEDTLS_GET_UINT32_LE(key, 16);
174*62c56f98SSadaf Ebrahimi ctx->state[9] = MBEDTLS_GET_UINT32_LE(key, 20);
175*62c56f98SSadaf Ebrahimi ctx->state[10] = MBEDTLS_GET_UINT32_LE(key, 24);
176*62c56f98SSadaf Ebrahimi ctx->state[11] = MBEDTLS_GET_UINT32_LE(key, 28);
177*62c56f98SSadaf Ebrahimi
178*62c56f98SSadaf Ebrahimi return 0;
179*62c56f98SSadaf Ebrahimi }
180*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_starts(mbedtls_chacha20_context * ctx,const unsigned char nonce[12],uint32_t counter)181*62c56f98SSadaf Ebrahimi int mbedtls_chacha20_starts(mbedtls_chacha20_context *ctx,
182*62c56f98SSadaf Ebrahimi const unsigned char nonce[12],
183*62c56f98SSadaf Ebrahimi uint32_t counter)
184*62c56f98SSadaf Ebrahimi {
185*62c56f98SSadaf Ebrahimi /* Counter */
186*62c56f98SSadaf Ebrahimi ctx->state[12] = counter;
187*62c56f98SSadaf Ebrahimi
188*62c56f98SSadaf Ebrahimi /* Nonce */
189*62c56f98SSadaf Ebrahimi ctx->state[13] = MBEDTLS_GET_UINT32_LE(nonce, 0);
190*62c56f98SSadaf Ebrahimi ctx->state[14] = MBEDTLS_GET_UINT32_LE(nonce, 4);
191*62c56f98SSadaf Ebrahimi ctx->state[15] = MBEDTLS_GET_UINT32_LE(nonce, 8);
192*62c56f98SSadaf Ebrahimi
193*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(ctx->keystream8, sizeof(ctx->keystream8));
194*62c56f98SSadaf Ebrahimi
195*62c56f98SSadaf Ebrahimi /* Initially, there's no keystream bytes available */
196*62c56f98SSadaf Ebrahimi ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
197*62c56f98SSadaf Ebrahimi
198*62c56f98SSadaf Ebrahimi return 0;
199*62c56f98SSadaf Ebrahimi }
200*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_update(mbedtls_chacha20_context * ctx,size_t size,const unsigned char * input,unsigned char * output)201*62c56f98SSadaf Ebrahimi int mbedtls_chacha20_update(mbedtls_chacha20_context *ctx,
202*62c56f98SSadaf Ebrahimi size_t size,
203*62c56f98SSadaf Ebrahimi const unsigned char *input,
204*62c56f98SSadaf Ebrahimi unsigned char *output)
205*62c56f98SSadaf Ebrahimi {
206*62c56f98SSadaf Ebrahimi size_t offset = 0U;
207*62c56f98SSadaf Ebrahimi
208*62c56f98SSadaf Ebrahimi /* Use leftover keystream bytes, if available */
209*62c56f98SSadaf Ebrahimi while (size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES) {
210*62c56f98SSadaf Ebrahimi output[offset] = input[offset]
211*62c56f98SSadaf Ebrahimi ^ ctx->keystream8[ctx->keystream_bytes_used];
212*62c56f98SSadaf Ebrahimi
213*62c56f98SSadaf Ebrahimi ctx->keystream_bytes_used++;
214*62c56f98SSadaf Ebrahimi offset++;
215*62c56f98SSadaf Ebrahimi size--;
216*62c56f98SSadaf Ebrahimi }
217*62c56f98SSadaf Ebrahimi
218*62c56f98SSadaf Ebrahimi /* Process full blocks */
219*62c56f98SSadaf Ebrahimi while (size >= CHACHA20_BLOCK_SIZE_BYTES) {
220*62c56f98SSadaf Ebrahimi /* Generate new keystream block and increment counter */
221*62c56f98SSadaf Ebrahimi chacha20_block(ctx->state, ctx->keystream8);
222*62c56f98SSadaf Ebrahimi ctx->state[CHACHA20_CTR_INDEX]++;
223*62c56f98SSadaf Ebrahimi
224*62c56f98SSadaf Ebrahimi mbedtls_xor(output + offset, input + offset, ctx->keystream8, 64U);
225*62c56f98SSadaf Ebrahimi
226*62c56f98SSadaf Ebrahimi offset += CHACHA20_BLOCK_SIZE_BYTES;
227*62c56f98SSadaf Ebrahimi size -= CHACHA20_BLOCK_SIZE_BYTES;
228*62c56f98SSadaf Ebrahimi }
229*62c56f98SSadaf Ebrahimi
230*62c56f98SSadaf Ebrahimi /* Last (partial) block */
231*62c56f98SSadaf Ebrahimi if (size > 0U) {
232*62c56f98SSadaf Ebrahimi /* Generate new keystream block and increment counter */
233*62c56f98SSadaf Ebrahimi chacha20_block(ctx->state, ctx->keystream8);
234*62c56f98SSadaf Ebrahimi ctx->state[CHACHA20_CTR_INDEX]++;
235*62c56f98SSadaf Ebrahimi
236*62c56f98SSadaf Ebrahimi mbedtls_xor(output + offset, input + offset, ctx->keystream8, size);
237*62c56f98SSadaf Ebrahimi
238*62c56f98SSadaf Ebrahimi ctx->keystream_bytes_used = size;
239*62c56f98SSadaf Ebrahimi
240*62c56f98SSadaf Ebrahimi }
241*62c56f98SSadaf Ebrahimi
242*62c56f98SSadaf Ebrahimi return 0;
243*62c56f98SSadaf Ebrahimi }
244*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_crypt(const unsigned char key[32],const unsigned char nonce[12],uint32_t counter,size_t data_len,const unsigned char * input,unsigned char * output)245*62c56f98SSadaf Ebrahimi int mbedtls_chacha20_crypt(const unsigned char key[32],
246*62c56f98SSadaf Ebrahimi const unsigned char nonce[12],
247*62c56f98SSadaf Ebrahimi uint32_t counter,
248*62c56f98SSadaf Ebrahimi size_t data_len,
249*62c56f98SSadaf Ebrahimi const unsigned char *input,
250*62c56f98SSadaf Ebrahimi unsigned char *output)
251*62c56f98SSadaf Ebrahimi {
252*62c56f98SSadaf Ebrahimi mbedtls_chacha20_context ctx;
253*62c56f98SSadaf Ebrahimi int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
254*62c56f98SSadaf Ebrahimi
255*62c56f98SSadaf Ebrahimi mbedtls_chacha20_init(&ctx);
256*62c56f98SSadaf Ebrahimi
257*62c56f98SSadaf Ebrahimi ret = mbedtls_chacha20_setkey(&ctx, key);
258*62c56f98SSadaf Ebrahimi if (ret != 0) {
259*62c56f98SSadaf Ebrahimi goto cleanup;
260*62c56f98SSadaf Ebrahimi }
261*62c56f98SSadaf Ebrahimi
262*62c56f98SSadaf Ebrahimi ret = mbedtls_chacha20_starts(&ctx, nonce, counter);
263*62c56f98SSadaf Ebrahimi if (ret != 0) {
264*62c56f98SSadaf Ebrahimi goto cleanup;
265*62c56f98SSadaf Ebrahimi }
266*62c56f98SSadaf Ebrahimi
267*62c56f98SSadaf Ebrahimi ret = mbedtls_chacha20_update(&ctx, data_len, input, output);
268*62c56f98SSadaf Ebrahimi
269*62c56f98SSadaf Ebrahimi cleanup:
270*62c56f98SSadaf Ebrahimi mbedtls_chacha20_free(&ctx);
271*62c56f98SSadaf Ebrahimi return ret;
272*62c56f98SSadaf Ebrahimi }
273*62c56f98SSadaf Ebrahimi
274*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_CHACHA20_ALT */
275*62c56f98SSadaf Ebrahimi
276*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SELF_TEST)
277*62c56f98SSadaf Ebrahimi
278*62c56f98SSadaf Ebrahimi static const unsigned char test_keys[2][32] =
279*62c56f98SSadaf Ebrahimi {
280*62c56f98SSadaf Ebrahimi {
281*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
285*62c56f98SSadaf Ebrahimi },
286*62c56f98SSadaf Ebrahimi {
287*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
291*62c56f98SSadaf Ebrahimi }
292*62c56f98SSadaf Ebrahimi };
293*62c56f98SSadaf Ebrahimi
294*62c56f98SSadaf Ebrahimi static const unsigned char test_nonces[2][12] =
295*62c56f98SSadaf Ebrahimi {
296*62c56f98SSadaf Ebrahimi {
297*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00
299*62c56f98SSadaf Ebrahimi },
300*62c56f98SSadaf Ebrahimi {
301*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x02
303*62c56f98SSadaf Ebrahimi }
304*62c56f98SSadaf Ebrahimi };
305*62c56f98SSadaf Ebrahimi
306*62c56f98SSadaf Ebrahimi static const uint32_t test_counters[2] =
307*62c56f98SSadaf Ebrahimi {
308*62c56f98SSadaf Ebrahimi 0U,
309*62c56f98SSadaf Ebrahimi 1U
310*62c56f98SSadaf Ebrahimi };
311*62c56f98SSadaf Ebrahimi
312*62c56f98SSadaf Ebrahimi static const unsigned char test_input[2][375] =
313*62c56f98SSadaf Ebrahimi {
314*62c56f98SSadaf Ebrahimi {
315*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322*62c56f98SSadaf Ebrahimi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
323*62c56f98SSadaf Ebrahimi },
324*62c56f98SSadaf Ebrahimi {
325*62c56f98SSadaf Ebrahimi 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
326*62c56f98SSadaf Ebrahimi 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
327*62c56f98SSadaf Ebrahimi 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
328*62c56f98SSadaf Ebrahimi 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
329*62c56f98SSadaf Ebrahimi 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
330*62c56f98SSadaf Ebrahimi 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
331*62c56f98SSadaf Ebrahimi 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
332*62c56f98SSadaf Ebrahimi 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
333*62c56f98SSadaf Ebrahimi 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
334*62c56f98SSadaf Ebrahimi 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
335*62c56f98SSadaf Ebrahimi 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
336*62c56f98SSadaf Ebrahimi 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
337*62c56f98SSadaf Ebrahimi 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
338*62c56f98SSadaf Ebrahimi 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
339*62c56f98SSadaf Ebrahimi 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
340*62c56f98SSadaf Ebrahimi 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
341*62c56f98SSadaf Ebrahimi 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
342*62c56f98SSadaf Ebrahimi 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
343*62c56f98SSadaf Ebrahimi 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
344*62c56f98SSadaf Ebrahimi 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
345*62c56f98SSadaf Ebrahimi 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
346*62c56f98SSadaf Ebrahimi 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
347*62c56f98SSadaf Ebrahimi 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
348*62c56f98SSadaf Ebrahimi 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
349*62c56f98SSadaf Ebrahimi 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
350*62c56f98SSadaf Ebrahimi 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
351*62c56f98SSadaf Ebrahimi 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
352*62c56f98SSadaf Ebrahimi 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
353*62c56f98SSadaf Ebrahimi 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
354*62c56f98SSadaf Ebrahimi 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
355*62c56f98SSadaf Ebrahimi 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
356*62c56f98SSadaf Ebrahimi 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
357*62c56f98SSadaf Ebrahimi 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
358*62c56f98SSadaf Ebrahimi 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
359*62c56f98SSadaf Ebrahimi 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
360*62c56f98SSadaf Ebrahimi 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
361*62c56f98SSadaf Ebrahimi 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
362*62c56f98SSadaf Ebrahimi 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
363*62c56f98SSadaf Ebrahimi 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
364*62c56f98SSadaf Ebrahimi 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
365*62c56f98SSadaf Ebrahimi 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
366*62c56f98SSadaf Ebrahimi 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
367*62c56f98SSadaf Ebrahimi 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
368*62c56f98SSadaf Ebrahimi 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
369*62c56f98SSadaf Ebrahimi 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
370*62c56f98SSadaf Ebrahimi 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
371*62c56f98SSadaf Ebrahimi 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
372*62c56f98SSadaf Ebrahimi }
373*62c56f98SSadaf Ebrahimi };
374*62c56f98SSadaf Ebrahimi
375*62c56f98SSadaf Ebrahimi static const unsigned char test_output[2][375] =
376*62c56f98SSadaf Ebrahimi {
377*62c56f98SSadaf Ebrahimi {
378*62c56f98SSadaf Ebrahimi 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
379*62c56f98SSadaf Ebrahimi 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
380*62c56f98SSadaf Ebrahimi 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
381*62c56f98SSadaf Ebrahimi 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
382*62c56f98SSadaf Ebrahimi 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
383*62c56f98SSadaf Ebrahimi 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
384*62c56f98SSadaf Ebrahimi 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
385*62c56f98SSadaf Ebrahimi 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
386*62c56f98SSadaf Ebrahimi },
387*62c56f98SSadaf Ebrahimi {
388*62c56f98SSadaf Ebrahimi 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
389*62c56f98SSadaf Ebrahimi 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
390*62c56f98SSadaf Ebrahimi 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
391*62c56f98SSadaf Ebrahimi 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
392*62c56f98SSadaf Ebrahimi 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
393*62c56f98SSadaf Ebrahimi 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
394*62c56f98SSadaf Ebrahimi 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
395*62c56f98SSadaf Ebrahimi 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
396*62c56f98SSadaf Ebrahimi 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
397*62c56f98SSadaf Ebrahimi 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
398*62c56f98SSadaf Ebrahimi 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
399*62c56f98SSadaf Ebrahimi 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
400*62c56f98SSadaf Ebrahimi 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
401*62c56f98SSadaf Ebrahimi 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
402*62c56f98SSadaf Ebrahimi 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
403*62c56f98SSadaf Ebrahimi 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
404*62c56f98SSadaf Ebrahimi 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
405*62c56f98SSadaf Ebrahimi 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
406*62c56f98SSadaf Ebrahimi 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
407*62c56f98SSadaf Ebrahimi 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
408*62c56f98SSadaf Ebrahimi 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
409*62c56f98SSadaf Ebrahimi 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
410*62c56f98SSadaf Ebrahimi 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
411*62c56f98SSadaf Ebrahimi 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
412*62c56f98SSadaf Ebrahimi 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
413*62c56f98SSadaf Ebrahimi 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
414*62c56f98SSadaf Ebrahimi 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
415*62c56f98SSadaf Ebrahimi 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
416*62c56f98SSadaf Ebrahimi 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
417*62c56f98SSadaf Ebrahimi 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
418*62c56f98SSadaf Ebrahimi 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
419*62c56f98SSadaf Ebrahimi 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
420*62c56f98SSadaf Ebrahimi 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
421*62c56f98SSadaf Ebrahimi 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
422*62c56f98SSadaf Ebrahimi 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
423*62c56f98SSadaf Ebrahimi 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
424*62c56f98SSadaf Ebrahimi 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
425*62c56f98SSadaf Ebrahimi 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
426*62c56f98SSadaf Ebrahimi 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
427*62c56f98SSadaf Ebrahimi 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
428*62c56f98SSadaf Ebrahimi 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
429*62c56f98SSadaf Ebrahimi 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
430*62c56f98SSadaf Ebrahimi 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
431*62c56f98SSadaf Ebrahimi 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
432*62c56f98SSadaf Ebrahimi 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
433*62c56f98SSadaf Ebrahimi 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
434*62c56f98SSadaf Ebrahimi 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
435*62c56f98SSadaf Ebrahimi }
436*62c56f98SSadaf Ebrahimi };
437*62c56f98SSadaf Ebrahimi
438*62c56f98SSadaf Ebrahimi static const size_t test_lengths[2] =
439*62c56f98SSadaf Ebrahimi {
440*62c56f98SSadaf Ebrahimi 64U,
441*62c56f98SSadaf Ebrahimi 375U
442*62c56f98SSadaf Ebrahimi };
443*62c56f98SSadaf Ebrahimi
444*62c56f98SSadaf Ebrahimi /* Make sure no other definition is already present. */
445*62c56f98SSadaf Ebrahimi #undef ASSERT
446*62c56f98SSadaf Ebrahimi
447*62c56f98SSadaf Ebrahimi #define ASSERT(cond, args) \
448*62c56f98SSadaf Ebrahimi do \
449*62c56f98SSadaf Ebrahimi { \
450*62c56f98SSadaf Ebrahimi if (!(cond)) \
451*62c56f98SSadaf Ebrahimi { \
452*62c56f98SSadaf Ebrahimi if (verbose != 0) \
453*62c56f98SSadaf Ebrahimi mbedtls_printf args; \
454*62c56f98SSadaf Ebrahimi \
455*62c56f98SSadaf Ebrahimi return -1; \
456*62c56f98SSadaf Ebrahimi } \
457*62c56f98SSadaf Ebrahimi } \
458*62c56f98SSadaf Ebrahimi while (0)
459*62c56f98SSadaf Ebrahimi
mbedtls_chacha20_self_test(int verbose)460*62c56f98SSadaf Ebrahimi int mbedtls_chacha20_self_test(int verbose)
461*62c56f98SSadaf Ebrahimi {
462*62c56f98SSadaf Ebrahimi unsigned char output[381];
463*62c56f98SSadaf Ebrahimi unsigned i;
464*62c56f98SSadaf Ebrahimi int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
465*62c56f98SSadaf Ebrahimi
466*62c56f98SSadaf Ebrahimi for (i = 0U; i < 2U; i++) {
467*62c56f98SSadaf Ebrahimi if (verbose != 0) {
468*62c56f98SSadaf Ebrahimi mbedtls_printf(" ChaCha20 test %u ", i);
469*62c56f98SSadaf Ebrahimi }
470*62c56f98SSadaf Ebrahimi
471*62c56f98SSadaf Ebrahimi ret = mbedtls_chacha20_crypt(test_keys[i],
472*62c56f98SSadaf Ebrahimi test_nonces[i],
473*62c56f98SSadaf Ebrahimi test_counters[i],
474*62c56f98SSadaf Ebrahimi test_lengths[i],
475*62c56f98SSadaf Ebrahimi test_input[i],
476*62c56f98SSadaf Ebrahimi output);
477*62c56f98SSadaf Ebrahimi
478*62c56f98SSadaf Ebrahimi ASSERT(0 == ret, ("error code: %i\n", ret));
479*62c56f98SSadaf Ebrahimi
480*62c56f98SSadaf Ebrahimi ASSERT(0 == memcmp(output, test_output[i], test_lengths[i]),
481*62c56f98SSadaf Ebrahimi ("failed (output)\n"));
482*62c56f98SSadaf Ebrahimi
483*62c56f98SSadaf Ebrahimi if (verbose != 0) {
484*62c56f98SSadaf Ebrahimi mbedtls_printf("passed\n");
485*62c56f98SSadaf Ebrahimi }
486*62c56f98SSadaf Ebrahimi }
487*62c56f98SSadaf Ebrahimi
488*62c56f98SSadaf Ebrahimi if (verbose != 0) {
489*62c56f98SSadaf Ebrahimi mbedtls_printf("\n");
490*62c56f98SSadaf Ebrahimi }
491*62c56f98SSadaf Ebrahimi
492*62c56f98SSadaf Ebrahimi return 0;
493*62c56f98SSadaf Ebrahimi }
494*62c56f98SSadaf Ebrahimi
495*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SELF_TEST */
496*62c56f98SSadaf Ebrahimi
497*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_CHACHA20_C */
498