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