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 ((uint32_t) ((value) << (amount)) | ((value) >> (32 - (amount)))) 41 42#define CHACHA20_CTR_INDEX (12U) 43 44#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 */ 61static 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{ 67 /* a += b; d ^= a; d <<<= 16; */ 68 state[a] += state[b]; 69 state[d] ^= state[a]; 70 state[d] = ROTL32(state[d], 16); 71 72 /* c += d; b ^= c; b <<<= 12 */ 73 state[c] += state[d]; 74 state[b] ^= state[c]; 75 state[b] = ROTL32(state[b], 12); 76 77 /* a += b; d ^= a; d <<<= 8; */ 78 state[a] += state[b]; 79 state[d] ^= state[a]; 80 state[d] = ROTL32(state[d], 8); 81 82 /* c += d; b ^= c; b <<<= 7; */ 83 state[c] += state[d]; 84 state[b] ^= state[c]; 85 state[b] = ROTL32(state[b], 7); 86} 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 */ 96static void chacha20_inner_block(uint32_t state[16]) 97{ 98 chacha20_quarter_round(state, 0, 4, 8, 12); 99 chacha20_quarter_round(state, 1, 5, 9, 13); 100 chacha20_quarter_round(state, 2, 6, 10, 14); 101 chacha20_quarter_round(state, 3, 7, 11, 15); 102 103 chacha20_quarter_round(state, 0, 5, 10, 15); 104 chacha20_quarter_round(state, 1, 6, 11, 12); 105 chacha20_quarter_round(state, 2, 7, 8, 13); 106 chacha20_quarter_round(state, 3, 4, 9, 14); 107} 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 */ 115static void chacha20_block(const uint32_t initial_state[16], 116 unsigned char keystream[64]) 117{ 118 uint32_t working_state[16]; 119 size_t i; 120 121 memcpy(working_state, 122 initial_state, 123 CHACHA20_BLOCK_SIZE_BYTES); 124 125 for (i = 0U; i < 10U; i++) { 126 chacha20_inner_block(working_state); 127 } 128 129 working_state[0] += initial_state[0]; 130 working_state[1] += initial_state[1]; 131 working_state[2] += initial_state[2]; 132 working_state[3] += initial_state[3]; 133 working_state[4] += initial_state[4]; 134 working_state[5] += initial_state[5]; 135 working_state[6] += initial_state[6]; 136 working_state[7] += initial_state[7]; 137 working_state[8] += initial_state[8]; 138 working_state[9] += initial_state[9]; 139 working_state[10] += initial_state[10]; 140 working_state[11] += initial_state[11]; 141 working_state[12] += initial_state[12]; 142 working_state[13] += initial_state[13]; 143 working_state[14] += initial_state[14]; 144 working_state[15] += initial_state[15]; 145 146 for (i = 0U; i < 16; i++) { 147 size_t offset = i * 4U; 148 149 MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset); 150 } 151 152 mbedtls_platform_zeroize(working_state, sizeof(working_state)); 153} 154 155void mbedtls_chacha20_init(mbedtls_chacha20_context *ctx) 156{ 157 mbedtls_platform_zeroize(ctx->state, sizeof(ctx->state)); 158 mbedtls_platform_zeroize(ctx->keystream8, sizeof(ctx->keystream8)); 159 160 /* Initially, there's no keystream bytes available */ 161 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; 162} 163 164void mbedtls_chacha20_free(mbedtls_chacha20_context *ctx) 165{ 166 if (ctx != NULL) { 167 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_chacha20_context)); 168 } 169} 170 171int mbedtls_chacha20_setkey(mbedtls_chacha20_context *ctx, 172 const unsigned char key[32]) 173{ 174 /* ChaCha20 constants - the string "expand 32-byte k" */ 175 ctx->state[0] = 0x61707865; 176 ctx->state[1] = 0x3320646e; 177 ctx->state[2] = 0x79622d32; 178 ctx->state[3] = 0x6b206574; 179 180 /* Set key */ 181 ctx->state[4] = MBEDTLS_GET_UINT32_LE(key, 0); 182 ctx->state[5] = MBEDTLS_GET_UINT32_LE(key, 4); 183 ctx->state[6] = MBEDTLS_GET_UINT32_LE(key, 8); 184 ctx->state[7] = MBEDTLS_GET_UINT32_LE(key, 12); 185 ctx->state[8] = MBEDTLS_GET_UINT32_LE(key, 16); 186 ctx->state[9] = MBEDTLS_GET_UINT32_LE(key, 20); 187 ctx->state[10] = MBEDTLS_GET_UINT32_LE(key, 24); 188 ctx->state[11] = MBEDTLS_GET_UINT32_LE(key, 28); 189 190 return 0; 191} 192 193int mbedtls_chacha20_starts(mbedtls_chacha20_context *ctx, 194 const unsigned char nonce[12], 195 uint32_t counter) 196{ 197 /* Counter */ 198 ctx->state[12] = counter; 199 200 /* Nonce */ 201 ctx->state[13] = MBEDTLS_GET_UINT32_LE(nonce, 0); 202 ctx->state[14] = MBEDTLS_GET_UINT32_LE(nonce, 4); 203 ctx->state[15] = MBEDTLS_GET_UINT32_LE(nonce, 8); 204 205 mbedtls_platform_zeroize(ctx->keystream8, sizeof(ctx->keystream8)); 206 207 /* Initially, there's no keystream bytes available */ 208 ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; 209 210 return 0; 211} 212 213int mbedtls_chacha20_update(mbedtls_chacha20_context *ctx, 214 size_t size, 215 const unsigned char *input, 216 unsigned char *output) 217{ 218 size_t offset = 0U; 219 220 /* Use leftover keystream bytes, if available */ 221 while (size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES) { 222 output[offset] = input[offset] 223 ^ ctx->keystream8[ctx->keystream_bytes_used]; 224 225 ctx->keystream_bytes_used++; 226 offset++; 227 size--; 228 } 229 230 /* Process full blocks */ 231 while (size >= CHACHA20_BLOCK_SIZE_BYTES) { 232 /* Generate new keystream block and increment counter */ 233 chacha20_block(ctx->state, ctx->keystream8); 234 ctx->state[CHACHA20_CTR_INDEX]++; 235 236 mbedtls_xor(output + offset, input + offset, ctx->keystream8, 64U); 237 238 offset += CHACHA20_BLOCK_SIZE_BYTES; 239 size -= CHACHA20_BLOCK_SIZE_BYTES; 240 } 241 242 /* Last (partial) block */ 243 if (size > 0U) { 244 /* Generate new keystream block and increment counter */ 245 chacha20_block(ctx->state, ctx->keystream8); 246 ctx->state[CHACHA20_CTR_INDEX]++; 247 248 mbedtls_xor(output + offset, input + offset, ctx->keystream8, size); 249 250 ctx->keystream_bytes_used = size; 251 252 } 253 254 return 0; 255} 256 257int 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{ 264 mbedtls_chacha20_context ctx; 265 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 266 267 mbedtls_chacha20_init(&ctx); 268 269 ret = mbedtls_chacha20_setkey(&ctx, key); 270 if (ret != 0) { 271 goto cleanup; 272 } 273 274 ret = mbedtls_chacha20_starts(&ctx, nonce, counter); 275 if (ret != 0) { 276 goto cleanup; 277 } 278 279 ret = mbedtls_chacha20_update(&ctx, data_len, input, output); 280 281cleanup: 282 mbedtls_chacha20_free(&ctx); 283 return ret; 284} 285 286#endif /* !MBEDTLS_CHACHA20_ALT */ 287 288#if defined(MBEDTLS_SELF_TEST) 289 290static 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 306static 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 318static const uint32_t test_counters[2] = 319{ 320 0U, 321 1U 322}; 323 324static 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 387static 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 450static 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 do \ 461 { \ 462 if (!(cond)) \ 463 { \ 464 if (verbose != 0) \ 465 mbedtls_printf args; \ 466 \ 467 return -1; \ 468 } \ 469 } \ 470 while (0) 471 472int mbedtls_chacha20_self_test(int verbose) 473{ 474 unsigned char output[381]; 475 unsigned i; 476 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 477 478 for (i = 0U; i < 2U; i++) { 479 if (verbose != 0) { 480 mbedtls_printf(" ChaCha20 test %u ", i); 481 } 482 483 ret = mbedtls_chacha20_crypt(test_keys[i], 484 test_nonces[i], 485 test_counters[i], 486 test_lengths[i], 487 test_input[i], 488 output); 489 490 ASSERT(0 == ret, ("error code: %i\n", ret)); 491 492 ASSERT(0 == memcmp(output, test_output[i], test_lengths[i]), 493 ("failed (output)\n")); 494 495 if (verbose != 0) { 496 mbedtls_printf("passed\n"); 497 } 498 } 499 500 if (verbose != 0) { 501 mbedtls_printf("\n"); 502 } 503 504 return 0; 505} 506 507#endif /* MBEDTLS_SELF_TEST */ 508 509#endif /* !MBEDTLS_CHACHA20_C */ 510