Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aria.c Source File

aria.c

00001 /*
00002  *  ARIA implementation
00003  *
00004  *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 
00022 /*
00023  * This implementation is based on the following standards:
00024  * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf
00025  * [2] https://tools.ietf.org/html/rfc5794
00026  */
00027 
00028 #if !defined(MBEDTLS_CONFIG_FILE)
00029 #include "mbedtls/config.h"
00030 #else
00031 #include MBEDTLS_CONFIG_FILE
00032 #endif
00033 
00034 #if defined(MBEDTLS_ARIA_C)
00035 
00036 #include "mbedtls/aria.h"
00037 
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_ARIA_ALT)
00050 
00051 #include "mbedtls/platform_util.h"
00052 
00053 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
00054     !defined(inline) && !defined(__cplusplus)
00055 #define inline __inline
00056 #endif
00057 
00058 /*
00059  * 32-bit integer manipulation macros (little endian)
00060  */
00061 #ifndef GET_UINT32_LE
00062 #define GET_UINT32_LE( n, b, i )                \
00063 {                                               \
00064     (n) = ( (uint32_t) (b)[(i)    ]       )     \
00065         | ( (uint32_t) (b)[(i) + 1] <<  8 )     \
00066         | ( (uint32_t) (b)[(i) + 2] << 16 )     \
00067         | ( (uint32_t) (b)[(i) + 3] << 24 );    \
00068 }
00069 #endif
00070 
00071 #ifndef PUT_UINT32_LE
00072 #define PUT_UINT32_LE( n, b, i )                                \
00073 {                                                               \
00074     (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
00075     (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
00076     (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
00077     (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
00078 }
00079 #endif
00080 
00081 /*
00082  * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
00083  *
00084  * This is submatrix P1 in [1] Appendix B.1
00085  *
00086  * Common compilers fail to translate this to minimal number of instructions,
00087  * so let's provide asm versions for common platforms with C fallback.
00088  */
00089 #if defined(MBEDTLS_HAVE_ASM)
00090 #if defined(__arm__) /* rev16 available from v6 up */
00091 /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
00092 #if defined(__GNUC__) && \
00093     ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \
00094     __ARM_ARCH >= 6
00095 static inline uint32_t aria_p1( uint32_t x )
00096 {
00097     uint32_t r;
00098     __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) );
00099     return( r );
00100 }
00101 #define ARIA_P1 aria_p1
00102 #elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
00103     ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 )
00104 static inline uint32_t aria_p1( uint32_t x )
00105 {
00106     uint32_t r;
00107     __asm( "rev16 r, x" );
00108     return( r );
00109 }
00110 #define ARIA_P1 aria_p1
00111 #endif
00112 #endif /* arm */
00113 #if defined(__GNUC__) && \
00114     defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
00115 /* I couldn't find an Intel equivalent of rev16, so two instructions */
00116 #define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) )
00117 #endif /* x86 gnuc */
00118 #endif /* MBEDTLS_HAVE_ASM && GNUC */
00119 #if !defined(ARIA_P1)
00120 #define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
00121 #endif
00122 
00123 /*
00124  * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
00125  *
00126  * This is submatrix P2 in [1] Appendix B.1
00127  *
00128  * Common compilers will translate this to a single instruction.
00129  */
00130 #define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
00131 
00132 /*
00133  * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
00134  *
00135  * This is submatrix P3 in [1] Appendix B.1
00136  *
00137  * Some compilers fail to translate this to a single instruction,
00138  * so let's provide asm versions for common platforms with C fallback.
00139  */
00140 #if defined(MBEDTLS_HAVE_ASM)
00141 #if defined(__arm__) /* rev available from v6 up */
00142 /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
00143 #if defined(__GNUC__) && \
00144     ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \
00145     __ARM_ARCH >= 6
00146 static inline uint32_t aria_p3( uint32_t x )
00147 {
00148     uint32_t r;
00149     __asm( "rev %0, %1" : "=l" (r) : "l" (x) );
00150     return( r );
00151 }
00152 #define ARIA_P3 aria_p3
00153 #elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
00154     ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 )
00155 static inline uint32_t aria_p3( uint32_t x )
00156 {
00157     uint32_t r;
00158     __asm( "rev r, x" );
00159     return( r );
00160 }
00161 #define ARIA_P3 aria_p3
00162 #endif
00163 #endif /* arm */
00164 #if defined(__GNUC__) && \
00165     defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
00166 static inline uint32_t aria_p3( uint32_t x )
00167 {
00168     __asm( "bswap %0" : "=r" (x) : "0" (x) );
00169     return( x );
00170 }
00171 #define ARIA_P3 aria_p3
00172 #endif /* x86 gnuc */
00173 #endif /* MBEDTLS_HAVE_ASM && GNUC */
00174 #if !defined(ARIA_P3)
00175 #define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) )
00176 #endif
00177 
00178 /*
00179  * ARIA Affine Transform
00180  * (a, b, c, d) = state in/out
00181  *
00182  * If we denote the first byte of input by 0, ..., the last byte by f,
00183  * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
00184  *
00185  * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple
00186  * rearrangements on adjacent pairs, output is:
00187  *
00188  * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
00189  *   = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
00190  * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd
00191  *   = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
00192  * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe
00193  *   = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
00194  * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef
00195  *   = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
00196  *
00197  * Note: another presentation of the A transform can be found as the first
00198  * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
00199  * The implementation below uses only P1 and P2 as they are sufficient.
00200  */
00201 static inline void aria_a( uint32_t *a, uint32_t *b,
00202                            uint32_t *c, uint32_t *d )
00203 {
00204     uint32_t ta, tb, tc;
00205     ta  =  *b;                      // 4567
00206     *b  =  *a;                      // 0123
00207     *a  =  ARIA_P2( ta );           // 6745
00208     tb  =  ARIA_P2( *d );           // efcd
00209     *d  =  ARIA_P1( *c );           // 98ba
00210     *c  =  ARIA_P1( tb );           // fedc
00211     ta  ^= *d;                      // 4567+98ba
00212     tc  =  ARIA_P2( *b );           // 2301
00213     ta  =  ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc
00214     tb  ^= ARIA_P2( *d );           // ba98+efcd
00215     tc  ^= ARIA_P1( *a );           // 2301+7654
00216     *b  ^= ta ^ tb;                 // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
00217     tb  =  ARIA_P2( tb ) ^ ta;      // 2301+5476+89ab+98ba+cdef+fedc
00218     *a  ^= ARIA_P1( tb );           // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
00219     ta  =  ARIA_P2( ta );           // 0123+7654+ab89+dcfe
00220     *d  ^= ARIA_P1( ta ) ^ tc;      // 1032+2301+6745+7654+98ba+ba98+cdef OUT
00221     tc  =  ARIA_P2( tc );           // 0123+5476
00222     *c  ^= ARIA_P1( tc ) ^ ta;      // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
00223 }
00224 
00225 /*
00226  * ARIA Substitution Layer SL1 / SL2
00227  * (a, b, c, d) = state in/out
00228  * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
00229  *
00230  * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
00231  * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
00232  */
00233 static inline void aria_sl( uint32_t *a, uint32_t *b,
00234                             uint32_t *c, uint32_t *d,
00235                             const uint8_t sa[256], const uint8_t sb[256],
00236                             const uint8_t sc[256], const uint8_t sd[256] )
00237 {
00238     *a = ( (uint32_t) sa[ *a        & 0xFF]       ) ^
00239          (((uint32_t) sb[(*a >>  8) & 0xFF]) <<  8) ^
00240          (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
00241          (((uint32_t) sd[ *a >> 24        ]) << 24);
00242     *b = ( (uint32_t) sa[ *b        & 0xFF]       ) ^
00243          (((uint32_t) sb[(*b >>  8) & 0xFF]) <<  8) ^
00244          (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
00245          (((uint32_t) sd[ *b >> 24        ]) << 24);
00246     *c = ( (uint32_t) sa[ *c        & 0xFF]       ) ^
00247          (((uint32_t) sb[(*c >>  8) & 0xFF]) <<  8) ^
00248          (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
00249          (((uint32_t) sd[ *c >> 24        ]) << 24);
00250     *d = ( (uint32_t) sa[ *d        & 0xFF]       ) ^
00251          (((uint32_t) sb[(*d >>  8) & 0xFF]) <<  8) ^
00252          (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
00253          (((uint32_t) sd[ *d >> 24        ]) << 24);
00254 }
00255 
00256 /*
00257  * S-Boxes
00258  */
00259 static const uint8_t aria_sb1[256] =
00260 {
00261     0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
00262     0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
00263     0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
00264     0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
00265     0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
00266     0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
00267     0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
00268     0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
00269     0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
00270     0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
00271     0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
00272     0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
00273     0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
00274     0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
00275     0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
00276     0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
00277     0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
00278     0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
00279     0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
00280     0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
00281     0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
00282     0xB0, 0x54, 0xBB, 0x16
00283 };
00284 
00285 static const uint8_t aria_sb2[256] =
00286 {
00287     0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
00288     0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
00289     0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
00290     0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
00291     0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
00292     0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
00293     0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
00294     0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
00295     0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
00296     0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
00297     0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
00298     0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
00299     0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
00300     0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
00301     0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
00302     0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
00303     0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
00304     0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
00305     0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
00306     0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
00307     0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
00308     0xAF, 0xBA, 0xB5, 0x81
00309 };
00310 
00311 static const uint8_t aria_is1[256] =
00312 {
00313     0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
00314     0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
00315     0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
00316     0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
00317     0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
00318     0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
00319     0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
00320     0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
00321     0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
00322     0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
00323     0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
00324     0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
00325     0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
00326     0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
00327     0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
00328     0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
00329     0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
00330     0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
00331     0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
00332     0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
00333     0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
00334     0x55, 0x21, 0x0C, 0x7D
00335 };
00336 
00337 static const uint8_t aria_is2[256] =
00338 {
00339     0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
00340     0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
00341     0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
00342     0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
00343     0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
00344     0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
00345     0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
00346     0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
00347     0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
00348     0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
00349     0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
00350     0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
00351     0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
00352     0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
00353     0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
00354     0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
00355     0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
00356     0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
00357     0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
00358     0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
00359     0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
00360     0x03, 0xA2, 0xAC, 0x60
00361 };
00362 
00363 /*
00364  * Helper for key schedule: r = FO( p, k ) ^ x
00365  */
00366 static void aria_fo_xor( uint32_t r[4], const uint32_t p[4],
00367                          const uint32_t k[4], const uint32_t x[4] )
00368 {
00369     uint32_t a, b, c, d;
00370 
00371     a = p[0] ^ k[0];
00372     b = p[1] ^ k[1];
00373     c = p[2] ^ k[2];
00374     d = p[3] ^ k[3];
00375 
00376     aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
00377     aria_a( &a, &b, &c, &d );
00378 
00379     r[0] = a ^ x[0];
00380     r[1] = b ^ x[1];
00381     r[2] = c ^ x[2];
00382     r[3] = d ^ x[3];
00383 }
00384 
00385 /*
00386  * Helper for key schedule: r = FE( p, k ) ^ x
00387  */
00388 static void aria_fe_xor( uint32_t r[4], const uint32_t p[4],
00389                          const uint32_t k[4], const uint32_t x[4] )
00390 {
00391     uint32_t a, b, c, d;
00392 
00393     a = p[0] ^ k[0];
00394     b = p[1] ^ k[1];
00395     c = p[2] ^ k[2];
00396     d = p[3] ^ k[3];
00397 
00398     aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
00399     aria_a( &a, &b, &c, &d );
00400 
00401     r[0] = a ^ x[0];
00402     r[1] = b ^ x[1];
00403     r[2] = c ^ x[2];
00404     r[3] = d ^ x[3];
00405 }
00406 
00407 /*
00408  * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
00409  *
00410  * We chose to store bytes into 32-bit words in little-endian format (see
00411  * GET/PUT_UINT32_LE) so we need to reverse bytes here.
00412  */
00413 static void aria_rot128( uint32_t r[4], const uint32_t a[4],
00414                          const uint32_t b[4], uint8_t n )
00415 {
00416     uint8_t i, j;
00417     uint32_t t, u;
00418 
00419     const uint8_t n1 = n % 32;              // bit offset
00420     const uint8_t n2 = n1 ? 32 - n1 : 0;    // reverse bit offset
00421 
00422     j = ( n / 32 ) % 4;                     // initial word offset
00423     t = ARIA_P3( b[j] );                    // big endian
00424     for( i = 0; i < 4; i++ )
00425     {
00426         j = ( j + 1 ) % 4;                  // get next word, big endian
00427         u = ARIA_P3( b[j] );
00428         t <<= n1;                           // rotate
00429         t |= u >> n2;
00430         t = ARIA_P3( t );                   // back to little endian
00431         r[i] = a[i] ^ t;                    // store
00432         t = u;                              // move to next word
00433     }
00434 }
00435 
00436 /*
00437  * Set encryption key
00438  */
00439 int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
00440                              const unsigned char *key, unsigned int keybits )
00441 {
00442     /* round constant masks */
00443     const uint32_t rc[3][4] =
00444     {
00445         {   0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA  },
00446         {   0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF  },
00447         {   0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804  }
00448     };
00449 
00450     int i;
00451     uint32_t w[4][4], *w2;
00452 
00453     if( keybits != 128 && keybits != 192 && keybits != 256 )
00454         return( MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH );
00455 
00456     /* Copy key to W0 (and potential remainder to W1) */
00457     GET_UINT32_LE( w[0][0], key,  0 );
00458     GET_UINT32_LE( w[0][1], key,  4 );
00459     GET_UINT32_LE( w[0][2], key,  8 );
00460     GET_UINT32_LE( w[0][3], key, 12 );
00461 
00462     memset( w[1], 0, 16 );
00463     if( keybits >= 192 )
00464     {
00465         GET_UINT32_LE( w[1][0], key, 16 );  // 192 bit key
00466         GET_UINT32_LE( w[1][1], key, 20 );
00467     }
00468     if( keybits == 256 )
00469     {
00470         GET_UINT32_LE( w[1][2], key, 24 );  // 256 bit key
00471         GET_UINT32_LE( w[1][3], key, 28 );
00472     }
00473 
00474     i = ( keybits - 128 ) >> 6;             // index: 0, 1, 2
00475     ctx->nr  = 12 + 2 * i;                   // no. rounds: 12, 14, 16
00476 
00477     aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR
00478     i = i < 2 ? i + 1 : 0;
00479     aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0
00480     i = i < 2 ? i + 1 : 0;
00481     aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1
00482 
00483     for( i = 0; i < 4; i++ )                // create round keys
00484     {
00485         w2 = w[(i + 1) & 3];
00486         aria_rot128( ctx->rk [i     ], w[i], w2, 128 - 19 );
00487         aria_rot128( ctx->rk [i +  4], w[i], w2, 128 - 31 );
00488         aria_rot128( ctx->rk [i +  8], w[i], w2,       61 );
00489         aria_rot128( ctx->rk [i + 12], w[i], w2,       31 );
00490     }
00491     aria_rot128( ctx->rk [16], w[0], w[1], 19 );
00492 
00493     /* w holds enough info to reconstruct the round keys */
00494     mbedtls_platform_zeroize( w, sizeof( w ) );
00495 
00496     return( 0 );
00497 }
00498 
00499 /*
00500  * Set decryption key
00501  */
00502 int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
00503                              const unsigned char *key, unsigned int keybits )
00504 {
00505     int i, j, k, ret;
00506 
00507     ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
00508     if( ret != 0 )
00509         return( ret );
00510 
00511     /* flip the order of round keys */
00512     for( i = 0, j = ctx->nr ; i < j; i++, j-- )
00513     {
00514         for( k = 0; k < 4; k++ )
00515         {
00516             uint32_t t = ctx->rk [i][k];
00517             ctx->rk [i][k] = ctx->rk [j][k];
00518             ctx->rk [j][k] = t;
00519         }
00520     }
00521 
00522     /* apply affine transform to middle keys */
00523     for( i = 1; i < ctx->nr ; i++ )
00524     {
00525         aria_a( &ctx->rk [i][0], &ctx->rk [i][1],
00526                 &ctx->rk [i][2], &ctx->rk [i][3] );
00527     }
00528 
00529     return( 0 );
00530 }
00531 
00532 /*
00533  * Encrypt a block
00534  */
00535 int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
00536                             const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
00537                             unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] )
00538 {
00539     int i;
00540 
00541     uint32_t a, b, c, d;
00542 
00543     GET_UINT32_LE( a, input,  0 );
00544     GET_UINT32_LE( b, input,  4 );
00545     GET_UINT32_LE( c, input,  8 );
00546     GET_UINT32_LE( d, input, 12 );
00547 
00548     i = 0;
00549     while( 1 )
00550     {
00551         a ^= ctx->rk [i][0];
00552         b ^= ctx->rk [i][1];
00553         c ^= ctx->rk [i][2];
00554         d ^= ctx->rk [i][3];
00555         i++;
00556 
00557         aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
00558         aria_a( &a, &b, &c, &d );
00559 
00560         a ^= ctx->rk [i][0];
00561         b ^= ctx->rk [i][1];
00562         c ^= ctx->rk [i][2];
00563         d ^= ctx->rk [i][3];
00564         i++;
00565 
00566         aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
00567         if( i >= ctx->nr  )
00568             break;
00569         aria_a( &a, &b, &c, &d );
00570     }
00571 
00572     /* final key mixing */
00573     a ^= ctx->rk [i][0];
00574     b ^= ctx->rk [i][1];
00575     c ^= ctx->rk [i][2];
00576     d ^= ctx->rk [i][3];
00577 
00578     PUT_UINT32_LE( a, output,  0 );
00579     PUT_UINT32_LE( b, output,  4 );
00580     PUT_UINT32_LE( c, output,  8 );
00581     PUT_UINT32_LE( d, output, 12 );
00582 
00583     return( 0 );
00584 }
00585 
00586 /* Initialize context */
00587 void mbedtls_aria_init( mbedtls_aria_context *ctx )
00588 {
00589     memset( ctx, 0, sizeof( mbedtls_aria_context ) );
00590 }
00591 
00592 /* Clear context */
00593 void mbedtls_aria_free( mbedtls_aria_context *ctx )
00594 {
00595     if( ctx == NULL )
00596         return;
00597 
00598     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) );
00599 }
00600 
00601 #if defined(MBEDTLS_CIPHER_MODE_CBC)
00602 /*
00603  * ARIA-CBC buffer encryption/decryption
00604  */
00605 int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
00606                             int mode,
00607                             size_t length,
00608                             unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
00609                             const unsigned char *input,
00610                             unsigned char *output )
00611 {
00612     int i;
00613     unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
00614 
00615     if( length % MBEDTLS_ARIA_BLOCKSIZE )
00616         return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
00617 
00618     if( mode == MBEDTLS_ARIA_DECRYPT )
00619     {
00620         while( length > 0 )
00621         {
00622             memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE );
00623             mbedtls_aria_crypt_ecb( ctx, input, output );
00624 
00625             for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ )
00626                 output[i] = (unsigned char)( output[i] ^ iv[i] );
00627 
00628             memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE );
00629 
00630             input  += MBEDTLS_ARIA_BLOCKSIZE;
00631             output += MBEDTLS_ARIA_BLOCKSIZE;
00632             length -= MBEDTLS_ARIA_BLOCKSIZE;
00633         }
00634     }
00635     else
00636     {
00637         while( length > 0 )
00638         {
00639             for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ )
00640                 output[i] = (unsigned char)( input[i] ^ iv[i] );
00641 
00642             mbedtls_aria_crypt_ecb( ctx, output, output );
00643             memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE );
00644 
00645             input  += MBEDTLS_ARIA_BLOCKSIZE;
00646             output += MBEDTLS_ARIA_BLOCKSIZE;
00647             length -= MBEDTLS_ARIA_BLOCKSIZE;
00648         }
00649     }
00650 
00651     return( 0 );
00652 }
00653 #endif /* MBEDTLS_CIPHER_MODE_CBC */
00654 
00655 #if defined(MBEDTLS_CIPHER_MODE_CFB)
00656 /*
00657  * ARIA-CFB128 buffer encryption/decryption
00658  */
00659 int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
00660                                int mode,
00661                                size_t length,
00662                                size_t *iv_off,
00663                                unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
00664                                const unsigned char *input,
00665                                unsigned char *output )
00666 {
00667     unsigned char c;
00668     size_t n = *iv_off;
00669 
00670     if( mode == MBEDTLS_ARIA_DECRYPT )
00671     {
00672         while( length-- )
00673         {
00674             if( n == 0 )
00675                 mbedtls_aria_crypt_ecb( ctx, iv, iv );
00676 
00677             c = *input++;
00678             *output++ = c ^ iv[n];
00679             iv[n] = c;
00680 
00681             n = ( n + 1 ) & 0x0F;
00682         }
00683     }
00684     else
00685     {
00686         while( length-- )
00687         {
00688             if( n == 0 )
00689                 mbedtls_aria_crypt_ecb( ctx, iv, iv );
00690 
00691             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
00692 
00693             n = ( n + 1 ) & 0x0F;
00694         }
00695     }
00696 
00697     *iv_off = n;
00698 
00699     return( 0 );
00700 }
00701 #endif /* MBEDTLS_CIPHER_MODE_CFB */
00702 
00703 #if defined(MBEDTLS_CIPHER_MODE_CTR)
00704 /*
00705  * ARIA-CTR buffer encryption/decryption
00706  */
00707 int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
00708                             size_t length,
00709                             size_t *nc_off,
00710                             unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
00711                             unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
00712                             const unsigned char *input,
00713                             unsigned char *output )
00714 {
00715     int c, i;
00716     size_t n = *nc_off;
00717 
00718     while( length-- )
00719     {
00720         if( n == 0 ) {
00721             mbedtls_aria_crypt_ecb( ctx, nonce_counter,
00722                                 stream_block );
00723 
00724             for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- )
00725                 if( ++nonce_counter[i - 1] != 0 )
00726                     break;
00727         }
00728         c = *input++;
00729         *output++ = (unsigned char)( c ^ stream_block[n] );
00730 
00731         n = ( n + 1 ) & 0x0F;
00732     }
00733 
00734     *nc_off = n;
00735 
00736     return( 0 );
00737 }
00738 #endif /* MBEDTLS_CIPHER_MODE_CTR */
00739 #endif /* !MBEDTLS_ARIA_ALT */
00740 
00741 #if defined(MBEDTLS_SELF_TEST)
00742 
00743 /*
00744  * Basic ARIA ECB test vectors from RFC 5794
00745  */
00746 static const uint8_t aria_test1_ecb_key[32] =           // test key
00747 {
00748     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,     // 128 bit
00749     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
00750     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,     // 192 bit
00751     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F      // 256 bit
00752 };
00753 
00754 static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] =            // plaintext
00755 {
00756     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // same for all
00757     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF      // key sizes
00758 };
00759 
00760 static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] =         // ciphertext
00761 {
00762     { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73,   // 128 bit
00763       0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
00764     { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA,   // 192 bit
00765       0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
00766     { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F,   // 256 bit
00767       0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
00768 };
00769 
00770 /*
00771  * Mode tests from "Test Vectors for ARIA"  Version 1.0
00772  * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
00773  */
00774 #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
00775     defined(MBEDTLS_CIPHER_MODE_CTR))
00776 static const uint8_t aria_test2_key[32] =
00777 {
00778     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 128 bit
00779     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
00780     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 192 bit
00781     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff      // 256 bit
00782 };
00783 
00784 static const uint8_t aria_test2_pt[48] =
00785 {
00786     0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa,     // same for all
00787     0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
00788     0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
00789     0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
00790     0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
00791     0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
00792 };
00793 #endif
00794 
00795 #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
00796 static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] =
00797 {
00798     0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,     // same for CBC, CFB
00799     0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0      // CTR has zero IV
00800 };
00801 #endif
00802 
00803 #if defined(MBEDTLS_CIPHER_MODE_CBC)
00804 static const uint8_t aria_test2_cbc_ct[3][48] =         // CBC ciphertext
00805 {
00806     { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10,   // 128-bit key
00807       0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
00808       0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
00809       0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
00810       0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
00811       0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
00812     { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c,   // 192-bit key
00813       0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
00814       0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
00815       0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
00816       0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
00817       0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
00818     { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1,   // 256-bit key
00819       0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
00820       0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
00821       0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
00822       0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
00823       0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
00824 };
00825 #endif /* MBEDTLS_CIPHER_MODE_CBC */
00826 
00827 #if defined(MBEDTLS_CIPHER_MODE_CFB)
00828 static const uint8_t aria_test2_cfb_ct[3][48] =         // CFB ciphertext
00829 {
00830     { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38,   // 128-bit key
00831       0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
00832       0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
00833       0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
00834       0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
00835       0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
00836     { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54,   // 192-bit key
00837       0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
00838       0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
00839       0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
00840       0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
00841       0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
00842     { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2,   // 256-bit key
00843       0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
00844       0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
00845       0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
00846       0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
00847       0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
00848 };
00849 #endif /* MBEDTLS_CIPHER_MODE_CFB */
00850 
00851 #if defined(MBEDTLS_CIPHER_MODE_CTR)
00852 static const uint8_t aria_test2_ctr_ct[3][48] =         // CTR ciphertext
00853 {
00854     { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c,   // 128-bit key
00855       0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
00856       0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
00857       0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
00858       0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
00859       0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
00860     { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19,   // 192-bit key
00861       0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
00862       0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
00863       0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
00864       0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
00865       0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
00866     { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17,   // 256-bit key
00867       0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
00868       0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
00869       0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
00870       0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
00871       0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
00872 };
00873 #endif /* MBEDTLS_CIPHER_MODE_CFB */
00874 
00875 #define ARIA_SELF_TEST_IF_FAIL              \
00876         {                                   \
00877             if( verbose )                   \
00878                 printf( "failed\n" );       \
00879             return( 1 );                    \
00880         } else {                            \
00881             if( verbose )                   \
00882                 printf( "passed\n" );       \
00883         }
00884 
00885 /*
00886  * Checkup routine
00887  */
00888 int mbedtls_aria_self_test( int verbose )
00889 {
00890     int i;
00891     uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
00892     mbedtls_aria_context ctx;
00893 
00894 #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
00895     size_t j;
00896 #endif
00897 
00898 #if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
00899      defined(MBEDTLS_CIPHER_MODE_CFB) || \
00900      defined(MBEDTLS_CIPHER_MODE_CTR))
00901     uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
00902 #endif
00903 
00904     /*
00905      * Test set 1
00906      */
00907     for( i = 0; i < 3; i++ )
00908     {
00909         /* test ECB encryption */
00910         if( verbose )
00911             printf( "  ARIA-ECB-%d (enc): ", 128 + 64 * i );
00912         mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
00913         mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk );
00914         if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
00915             ARIA_SELF_TEST_IF_FAIL;
00916 
00917         /* test ECB decryption */
00918         if( verbose )
00919             printf( "  ARIA-ECB-%d (dec): ", 128 + 64 * i );
00920         mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
00921         mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk );
00922         if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
00923             ARIA_SELF_TEST_IF_FAIL;
00924     }
00925     if( verbose )
00926         printf( "\n" );
00927 
00928     /*
00929      * Test set 2
00930      */
00931 #if defined(MBEDTLS_CIPHER_MODE_CBC)
00932     for( i = 0; i < 3; i++ )
00933     {
00934         /* Test CBC encryption */
00935         if( verbose )
00936             printf( "  ARIA-CBC-%d (enc): ", 128 + 64 * i );
00937         mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
00938         memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
00939         memset( buf, 0x55, sizeof( buf ) );
00940         mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
00941             aria_test2_pt, buf );
00942         if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
00943             ARIA_SELF_TEST_IF_FAIL;
00944 
00945         /* Test CBC decryption */
00946         if( verbose )
00947             printf( "  ARIA-CBC-%d (dec): ", 128 + 64 * i );
00948         mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i );
00949         memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
00950         memset( buf, 0xAA, sizeof( buf ) );
00951         mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
00952             aria_test2_cbc_ct[i], buf );
00953         if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
00954             ARIA_SELF_TEST_IF_FAIL;
00955     }
00956     if( verbose )
00957         printf( "\n" );
00958 
00959 #endif /* MBEDTLS_CIPHER_MODE_CBC */
00960 
00961 #if defined(MBEDTLS_CIPHER_MODE_CFB)
00962     for( i = 0; i < 3; i++ )
00963     {
00964         /* Test CFB encryption */
00965         if( verbose )
00966             printf( "  ARIA-CFB-%d (enc): ", 128 + 64 * i );
00967         mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
00968         memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
00969         memset( buf, 0x55, sizeof( buf ) );
00970         j = 0;
00971         mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
00972             aria_test2_pt, buf );
00973         if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
00974             ARIA_SELF_TEST_IF_FAIL;
00975 
00976         /* Test CFB decryption */
00977         if( verbose )
00978             printf( "  ARIA-CFB-%d (dec): ", 128 + 64 * i );
00979         mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
00980         memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
00981         memset( buf, 0xAA, sizeof( buf ) );
00982         j = 0;
00983         mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
00984             iv, aria_test2_cfb_ct[i], buf );
00985         if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
00986             ARIA_SELF_TEST_IF_FAIL;
00987     }
00988     if( verbose )
00989         printf( "\n" );
00990 #endif /* MBEDTLS_CIPHER_MODE_CFB */
00991 
00992 #if defined(MBEDTLS_CIPHER_MODE_CTR)
00993     for( i = 0; i < 3; i++ )
00994     {
00995         /* Test CTR encryption */
00996         if( verbose )
00997             printf( "  ARIA-CTR-%d (enc): ", 128 + 64 * i );
00998         mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
00999         memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE );                    // IV = 0
01000         memset( buf, 0x55, sizeof( buf ) );
01001         j = 0;
01002         mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
01003             aria_test2_pt, buf );
01004         if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
01005             ARIA_SELF_TEST_IF_FAIL;
01006 
01007         /* Test CTR decryption */
01008         if( verbose )
01009             printf( "  ARIA-CTR-%d (dec): ", 128 + 64 * i );
01010         mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
01011         memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE );                    // IV = 0
01012         memset( buf, 0xAA, sizeof( buf ) );
01013         j = 0;
01014         mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
01015             aria_test2_ctr_ct[i], buf );
01016         if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
01017             ARIA_SELF_TEST_IF_FAIL;
01018     }
01019     if( verbose )
01020         printf( "\n" );
01021 #endif /* MBEDTLS_CIPHER_MODE_CTR */
01022 
01023     return( 0 );
01024 }
01025 
01026 #endif /* MBEDTLS_SELF_TEST */
01027 
01028 #endif /* MBEDTLS_ARIA_C */