Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers chacha20.c Source File

chacha20.c

Go to the documentation of this file.
00001 /**
00002  * \file chacha20.c
00003  *
00004  * \brief ChaCha20 cipher.
00005  *
00006  * \author Daniel King <damaki.gh@gmail.com>
00007  *
00008  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
00009  *  SPDX-License-Identifier: Apache-2.0
00010  *
00011  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00012  *  not use this file except in compliance with the License.
00013  *  You may obtain a copy of the License at
00014  *
00015  *  http://www.apache.org/licenses/LICENSE-2.0
00016  *
00017  *  Unless required by applicable law or agreed to in writing, software
00018  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00019  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020  *  See the License for the specific language governing permissions and
00021  *  limitations under the License.
00022  *
00023  *  This file is part of mbed TLS (https://tls.mbed.org)
00024  */
00025 
00026 #if !defined(MBEDTLS_CONFIG_FILE)
00027 #include "mbedtls/config.h"
00028 #else
00029 #include MBEDTLS_CONFIG_FILE
00030 #endif
00031 
00032 #if defined(MBEDTLS_CHACHA20_C)
00033 
00034 #include "mbedtls/chacha20.h"
00035 #include "mbedtls/platform_util.h"
00036 
00037 #include <stddef.h>
00038 #include <string.h>
00039 
00040 #if defined(MBEDTLS_SELF_TEST)
00041 #if defined(MBEDTLS_PLATFORM_C)
00042 #include "mbedtls/platform.h"
00043 #else
00044 #include <stdio.h>
00045 #define mbedtls_printf printf
00046 #endif /* MBEDTLS_PLATFORM_C */
00047 #endif /* MBEDTLS_SELF_TEST */
00048 
00049 #if !defined(MBEDTLS_CHACHA20_ALT)
00050 
00051 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
00052     !defined(inline) && !defined(__cplusplus)
00053 #define inline __inline
00054 #endif
00055 
00056 #define BYTES_TO_U32_LE( data, offset )                           \
00057     ( (uint32_t) data[offset]                                     \
00058           | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 )   \
00059           | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 )  \
00060           | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 )  \
00061     )
00062 
00063 #define ROTL32( value, amount ) \
00064         ( (uint32_t) ( value << amount ) | ( value >> ( 32 - amount ) ) )
00065 
00066 #define CHACHA20_CTR_INDEX ( 12U )
00067 
00068 #define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
00069 
00070 /**
00071  * \brief           ChaCha20 quarter round operation.
00072  *
00073  *                  The quarter round is defined as follows (from RFC 7539):
00074  *                      1.  a += b; d ^= a; d <<<= 16;
00075  *                      2.  c += d; b ^= c; b <<<= 12;
00076  *                      3.  a += b; d ^= a; d <<<= 8;
00077  *                      4.  c += d; b ^= c; b <<<= 7;
00078  *
00079  * \param state     ChaCha20 state to modify.
00080  * \param a         The index of 'a' in the state.
00081  * \param b         The index of 'b' in the state.
00082  * \param c         The index of 'c' in the state.
00083  * \param d         The index of 'd' in the state.
00084  */
00085 static inline void chacha20_quarter_round( uint32_t state[16],
00086                                            size_t a,
00087                                            size_t b,
00088                                            size_t c,
00089                                            size_t d )
00090 {
00091     /* a += b; d ^= a; d <<<= 16; */
00092     state[a] += state[b];
00093     state[d] ^= state[a];
00094     state[d] = ROTL32( state[d], 16 );
00095 
00096     /* c += d; b ^= c; b <<<= 12 */
00097     state[c] += state[d];
00098     state[b] ^= state[c];
00099     state[b] = ROTL32( state[b], 12 );
00100 
00101     /* a += b; d ^= a; d <<<= 8; */
00102     state[a] += state[b];
00103     state[d] ^= state[a];
00104     state[d] = ROTL32( state[d], 8 );
00105 
00106     /* c += d; b ^= c; b <<<= 7; */
00107     state[c] += state[d];
00108     state[b] ^= state[c];
00109     state[b] = ROTL32( state[b], 7 );
00110 }
00111 
00112 /**
00113  * \brief           Perform the ChaCha20 inner block operation.
00114  *
00115  *                  This function performs two rounds: the column round and the
00116  *                  diagonal round.
00117  *
00118  * \param state     The ChaCha20 state to update.
00119  */
00120 static void chacha20_inner_block( uint32_t state[16] )
00121 {
00122     chacha20_quarter_round( state, 0, 4, 8,  12 );
00123     chacha20_quarter_round( state, 1, 5, 9,  13 );
00124     chacha20_quarter_round( state, 2, 6, 10, 14 );
00125     chacha20_quarter_round( state, 3, 7, 11, 15 );
00126 
00127     chacha20_quarter_round( state, 0, 5, 10, 15 );
00128     chacha20_quarter_round( state, 1, 6, 11, 12 );
00129     chacha20_quarter_round( state, 2, 7, 8,  13 );
00130     chacha20_quarter_round( state, 3, 4, 9,  14 );
00131 }
00132 
00133 /**
00134  * \brief               Generates a keystream block.
00135  *
00136  * \param initial_state The initial ChaCha20 state (key, nonce, counter).
00137  * \param keystream     Generated keystream bytes are written to this buffer.
00138  */
00139 static void chacha20_block( const uint32_t initial_state[16],
00140                             unsigned char keystream[64] )
00141 {
00142     uint32_t working_state[16];
00143     size_t i;
00144 
00145     memcpy( working_state,
00146             initial_state,
00147             CHACHA20_BLOCK_SIZE_BYTES );
00148 
00149     for( i = 0U; i < 10U; i++ )
00150         chacha20_inner_block( working_state );
00151 
00152     working_state[ 0] += initial_state[ 0];
00153     working_state[ 1] += initial_state[ 1];
00154     working_state[ 2] += initial_state[ 2];
00155     working_state[ 3] += initial_state[ 3];
00156     working_state[ 4] += initial_state[ 4];
00157     working_state[ 5] += initial_state[ 5];
00158     working_state[ 6] += initial_state[ 6];
00159     working_state[ 7] += initial_state[ 7];
00160     working_state[ 8] += initial_state[ 8];
00161     working_state[ 9] += initial_state[ 9];
00162     working_state[10] += initial_state[10];
00163     working_state[11] += initial_state[11];
00164     working_state[12] += initial_state[12];
00165     working_state[13] += initial_state[13];
00166     working_state[14] += initial_state[14];
00167     working_state[15] += initial_state[15];
00168 
00169     for( i = 0U; i < 16; i++ )
00170     {
00171         size_t offset = i * 4U;
00172 
00173         keystream[offset     ] = (unsigned char)( working_state[i]       );
00174         keystream[offset + 1U] = (unsigned char)( working_state[i] >>  8 );
00175         keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
00176         keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
00177     }
00178 
00179     mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
00180 }
00181 
00182 void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
00183 {
00184     if( ctx != NULL )
00185     {
00186         mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
00187         mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
00188 
00189         /* Initially, there's no keystream bytes available */
00190         ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
00191     }
00192 }
00193 
00194 void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
00195 {
00196     if( ctx != NULL )
00197     {
00198         mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
00199     }
00200 }
00201 
00202 int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
00203                             const unsigned char key[32] )
00204 {
00205     if( ( ctx == NULL ) || ( key == NULL ) )
00206     {
00207         return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
00208     }
00209 
00210     /* ChaCha20 constants - the string "expand 32-byte k" */
00211     ctx->state[0] = 0x61707865;
00212     ctx->state[1] = 0x3320646e;
00213     ctx->state[2] = 0x79622d32;
00214     ctx->state[3] = 0x6b206574;
00215 
00216     /* Set key */
00217     ctx->state[4]  = BYTES_TO_U32_LE( key, 0 );
00218     ctx->state[5]  = BYTES_TO_U32_LE( key, 4 );
00219     ctx->state[6]  = BYTES_TO_U32_LE( key, 8 );
00220     ctx->state[7]  = BYTES_TO_U32_LE( key, 12 );
00221     ctx->state[8]  = BYTES_TO_U32_LE( key, 16 );
00222     ctx->state[9]  = BYTES_TO_U32_LE( key, 20 );
00223     ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
00224     ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
00225 
00226     return( 0 );
00227 }
00228 
00229 int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
00230                              const unsigned char nonce[12],
00231                              uint32_t counter )
00232 {
00233     if( ( ctx == NULL ) || ( nonce == NULL ) )
00234     {
00235         return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
00236     }
00237 
00238     /* Counter */
00239     ctx->state[12] = counter;
00240 
00241     /* Nonce */
00242     ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
00243     ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
00244     ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
00245 
00246     mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
00247 
00248     /* Initially, there's no keystream bytes available */
00249     ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
00250 
00251     return( 0 );
00252 }
00253 
00254 int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
00255                               size_t size,
00256                               const unsigned char *input,
00257                               unsigned char *output )
00258 {
00259     size_t offset = 0U;
00260     size_t i;
00261 
00262     if( ctx == NULL )
00263     {
00264         return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
00265     }
00266     else if( ( size > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
00267     {
00268         /* input and output pointers are allowed to be NULL only if size == 0 */
00269         return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
00270     }
00271 
00272     /* Use leftover keystream bytes, if available */
00273     while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
00274     {
00275         output[offset] = input[offset]
00276                        ^ ctx->keystream8[ctx->keystream_bytes_used];
00277 
00278         ctx->keystream_bytes_used++;
00279         offset++;
00280         size--;
00281     }
00282 
00283     /* Process full blocks */
00284     while( size >= CHACHA20_BLOCK_SIZE_BYTES )
00285     {
00286         /* Generate new keystream block and increment counter */
00287         chacha20_block( ctx->state, ctx->keystream8 );
00288         ctx->state[CHACHA20_CTR_INDEX]++;
00289 
00290         for( i = 0U; i < 64U; i += 8U )
00291         {
00292             output[offset + i  ] = input[offset + i  ] ^ ctx->keystream8[i  ];
00293             output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
00294             output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
00295             output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
00296             output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
00297             output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
00298             output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
00299             output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
00300         }
00301 
00302         offset += CHACHA20_BLOCK_SIZE_BYTES;
00303         size   -= CHACHA20_BLOCK_SIZE_BYTES;
00304     }
00305 
00306     /* Last (partial) block */
00307     if( size > 0U )
00308     {
00309         /* Generate new keystream block and increment counter */
00310         chacha20_block( ctx->state, ctx->keystream8 );
00311         ctx->state[CHACHA20_CTR_INDEX]++;
00312 
00313         for( i = 0U; i < size; i++)
00314         {
00315             output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
00316         }
00317 
00318         ctx->keystream_bytes_used = size;
00319 
00320     }
00321 
00322     return( 0 );
00323 }
00324 
00325 int mbedtls_chacha20_crypt( const unsigned char key[32],
00326                             const unsigned char nonce[12],
00327                             uint32_t counter,
00328                             size_t data_len,
00329                             const unsigned char* input,
00330                             unsigned char* output )
00331 {
00332     mbedtls_chacha20_context ctx;
00333     int ret;
00334 
00335     mbedtls_chacha20_init( &ctx );
00336 
00337     ret = mbedtls_chacha20_setkey( &ctx, key );
00338     if( ret != 0 )
00339         goto cleanup;
00340 
00341     ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
00342     if( ret != 0 )
00343         goto cleanup;
00344 
00345     ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
00346 
00347 cleanup:
00348     mbedtls_chacha20_free( &ctx );
00349     return( ret );
00350 }
00351 
00352 #endif /* !MBEDTLS_CHACHA20_ALT */
00353 
00354 #if defined(MBEDTLS_SELF_TEST)
00355 
00356 static const unsigned char test_keys[2][32] =
00357 {
00358     {
00359         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00360         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00361         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00362         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00363     },
00364     {
00365         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00366         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00367         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00368         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
00369     }
00370 };
00371 
00372 static const unsigned char test_nonces[2][12] =
00373 {
00374     {
00375         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00376         0x00, 0x00, 0x00, 0x00
00377     },
00378     {
00379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00380         0x00, 0x00, 0x00, 0x02
00381     }
00382 };
00383 
00384 static const uint32_t test_counters[2] =
00385 {
00386     0U,
00387     1U
00388 };
00389 
00390 static const unsigned char test_input[2][375] =
00391 {
00392     {
00393         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00394         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00395         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00396         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00397         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00398         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00399         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00400         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00401     },
00402     {
00403         0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
00404         0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
00405         0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
00406         0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
00407         0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
00408         0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
00409         0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
00410         0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
00411         0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
00412         0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
00413         0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
00414         0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
00415         0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
00416         0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
00417         0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
00418         0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
00419         0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
00420         0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
00421         0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
00422         0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
00423         0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
00424         0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
00425         0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
00426         0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
00427         0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
00428         0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
00429         0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
00430         0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
00431         0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
00432         0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
00433         0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
00434         0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
00435         0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
00436         0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
00437         0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
00438         0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
00439         0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
00440         0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
00441         0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
00442         0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
00443         0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
00444         0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
00445         0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
00446         0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
00447         0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
00448         0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
00449         0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
00450     }
00451 };
00452 
00453 static const unsigned char test_output[2][375] =
00454 {
00455     {
00456         0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
00457         0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
00458         0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
00459         0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
00460         0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
00461         0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
00462         0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
00463         0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
00464     },
00465     {
00466         0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
00467         0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
00468         0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
00469         0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
00470         0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
00471         0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
00472         0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
00473         0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
00474         0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
00475         0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
00476         0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
00477         0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
00478         0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
00479         0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
00480         0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
00481         0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
00482         0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
00483         0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
00484         0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
00485         0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
00486         0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
00487         0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
00488         0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
00489         0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
00490         0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
00491         0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
00492         0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
00493         0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
00494         0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
00495         0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
00496         0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
00497         0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
00498         0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
00499         0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
00500         0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
00501         0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
00502         0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
00503         0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
00504         0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
00505         0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
00506         0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
00507         0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
00508         0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
00509         0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
00510         0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
00511         0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
00512         0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
00513     }
00514 };
00515 
00516 static const size_t test_lengths[2] =
00517 {
00518     64U,
00519     375U
00520 };
00521 
00522 #define ASSERT( cond, args )            \
00523     do                                  \
00524     {                                   \
00525         if( ! ( cond ) )                \
00526         {                               \
00527             if( verbose != 0 )          \
00528                 mbedtls_printf args;    \
00529                                         \
00530             return( -1 );               \
00531         }                               \
00532     }                                   \
00533     while( 0 )
00534 
00535 int mbedtls_chacha20_self_test( int verbose )
00536 {
00537     unsigned char output[381];
00538     unsigned i;
00539     int ret;
00540 
00541     for( i = 0U; i < 2U; i++ )
00542     {
00543         if( verbose != 0 )
00544             mbedtls_printf( "  ChaCha20 test %u ", i );
00545 
00546         ret = mbedtls_chacha20_crypt( test_keys[i],
00547                                       test_nonces[i],
00548                                       test_counters[i],
00549                                       test_lengths[i],
00550                                       test_input[i],
00551                                       output );
00552 
00553         ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
00554 
00555         ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
00556                 ( "failed (output)\n" ) );
00557 
00558         if( verbose != 0 )
00559             mbedtls_printf( "passed\n" );
00560     }
00561 
00562     if( verbose != 0 )
00563         mbedtls_printf( "\n" );
00564 
00565     return( 0 );
00566 }
00567 
00568 #endif /* MBEDTLS_SELF_TEST */
00569 
00570 #endif /* !MBEDTLS_CHACHA20_C */