Coverage Report

Created: 2025-07-01 06:54

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