Coverage Report

Created: 2024-08-17 06:45

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