13d3b0591SJens Wiklander /* 23d3b0591SJens Wiklander * ARIA implementation 33d3b0591SJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 63d3b0591SJens Wiklander * 73d3b0591SJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 83d3b0591SJens Wiklander * not use this file except in compliance with the License. 93d3b0591SJens Wiklander * You may obtain a copy of the License at 103d3b0591SJens Wiklander * 113d3b0591SJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 123d3b0591SJens Wiklander * 133d3b0591SJens Wiklander * Unless required by applicable law or agreed to in writing, software 143d3b0591SJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 153d3b0591SJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163d3b0591SJens Wiklander * See the License for the specific language governing permissions and 173d3b0591SJens Wiklander * limitations under the License. 183d3b0591SJens Wiklander */ 193d3b0591SJens Wiklander 203d3b0591SJens Wiklander /* 213d3b0591SJens Wiklander * This implementation is based on the following standards: 223d3b0591SJens Wiklander * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf 233d3b0591SJens Wiklander * [2] https://tools.ietf.org/html/rfc5794 243d3b0591SJens Wiklander */ 253d3b0591SJens Wiklander 267901324dSJerome Forissier #include "common.h" 273d3b0591SJens Wiklander 283d3b0591SJens Wiklander #if defined(MBEDTLS_ARIA_C) 293d3b0591SJens Wiklander 303d3b0591SJens Wiklander #include "mbedtls/aria.h" 313d3b0591SJens Wiklander 323d3b0591SJens Wiklander #include <string.h> 333d3b0591SJens Wiklander 343d3b0591SJens Wiklander #if defined(MBEDTLS_SELF_TEST) 353d3b0591SJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 363d3b0591SJens Wiklander #include "mbedtls/platform.h" 373d3b0591SJens Wiklander #else 383d3b0591SJens Wiklander #include <stdio.h> 393d3b0591SJens Wiklander #define mbedtls_printf printf 403d3b0591SJens Wiklander #endif /* MBEDTLS_PLATFORM_C */ 413d3b0591SJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 423d3b0591SJens Wiklander 433d3b0591SJens Wiklander #if !defined(MBEDTLS_ARIA_ALT) 443d3b0591SJens Wiklander 453d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 463d3b0591SJens Wiklander 473d3b0591SJens Wiklander #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ 483d3b0591SJens Wiklander !defined(inline) && !defined(__cplusplus) 493d3b0591SJens Wiklander #define inline __inline 503d3b0591SJens Wiklander #endif 513d3b0591SJens Wiklander 523d3b0591SJens Wiklander /* Parameter validation macros */ 533d3b0591SJens Wiklander #define ARIA_VALIDATE_RET( cond ) \ 543d3b0591SJens Wiklander MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ) 553d3b0591SJens Wiklander #define ARIA_VALIDATE( cond ) \ 563d3b0591SJens Wiklander MBEDTLS_INTERNAL_VALIDATE( cond ) 573d3b0591SJens Wiklander 583d3b0591SJens Wiklander /* 593d3b0591SJens Wiklander * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes 603d3b0591SJens Wiklander * 613d3b0591SJens Wiklander * This is submatrix P1 in [1] Appendix B.1 623d3b0591SJens Wiklander * 633d3b0591SJens Wiklander * Common compilers fail to translate this to minimal number of instructions, 643d3b0591SJens Wiklander * so let's provide asm versions for common platforms with C fallback. 653d3b0591SJens Wiklander */ 663d3b0591SJens Wiklander #if defined(MBEDTLS_HAVE_ASM) 673d3b0591SJens Wiklander #if defined(__arm__) /* rev16 available from v6 up */ 683d3b0591SJens Wiklander /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ 693d3b0591SJens Wiklander #if defined(__GNUC__) && \ 703d3b0591SJens Wiklander ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ 713d3b0591SJens Wiklander __ARM_ARCH >= 6 723d3b0591SJens Wiklander static inline uint32_t aria_p1( uint32_t x ) 733d3b0591SJens Wiklander { 743d3b0591SJens Wiklander uint32_t r; 753d3b0591SJens Wiklander __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) ); 763d3b0591SJens Wiklander return( r ); 773d3b0591SJens Wiklander } 783d3b0591SJens Wiklander #define ARIA_P1 aria_p1 793d3b0591SJens Wiklander #elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ 803d3b0591SJens Wiklander ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) 813d3b0591SJens Wiklander static inline uint32_t aria_p1( uint32_t x ) 823d3b0591SJens Wiklander { 833d3b0591SJens Wiklander uint32_t r; 843d3b0591SJens Wiklander __asm( "rev16 r, x" ); 853d3b0591SJens Wiklander return( r ); 863d3b0591SJens Wiklander } 873d3b0591SJens Wiklander #define ARIA_P1 aria_p1 883d3b0591SJens Wiklander #endif 893d3b0591SJens Wiklander #endif /* arm */ 903d3b0591SJens Wiklander #if defined(__GNUC__) && \ 913d3b0591SJens Wiklander defined(__i386__) || defined(__amd64__) || defined( __x86_64__) 923d3b0591SJens Wiklander /* I couldn't find an Intel equivalent of rev16, so two instructions */ 933d3b0591SJens Wiklander #define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) ) 943d3b0591SJens Wiklander #endif /* x86 gnuc */ 953d3b0591SJens Wiklander #endif /* MBEDTLS_HAVE_ASM && GNUC */ 963d3b0591SJens Wiklander #if !defined(ARIA_P1) 973d3b0591SJens Wiklander #define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8)) 983d3b0591SJens Wiklander #endif 993d3b0591SJens Wiklander 1003d3b0591SJens Wiklander /* 1013d3b0591SJens Wiklander * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits 1023d3b0591SJens Wiklander * 1033d3b0591SJens Wiklander * This is submatrix P2 in [1] Appendix B.1 1043d3b0591SJens Wiklander * 1053d3b0591SJens Wiklander * Common compilers will translate this to a single instruction. 1063d3b0591SJens Wiklander */ 1073d3b0591SJens Wiklander #define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16)) 1083d3b0591SJens Wiklander 1093d3b0591SJens Wiklander /* 1103d3b0591SJens Wiklander * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness 1113d3b0591SJens Wiklander * 1123d3b0591SJens Wiklander * This is submatrix P3 in [1] Appendix B.1 1133d3b0591SJens Wiklander * 1143d3b0591SJens Wiklander * Some compilers fail to translate this to a single instruction, 1153d3b0591SJens Wiklander * so let's provide asm versions for common platforms with C fallback. 1163d3b0591SJens Wiklander */ 1173d3b0591SJens Wiklander #if defined(MBEDTLS_HAVE_ASM) 1183d3b0591SJens Wiklander #if defined(__arm__) /* rev available from v6 up */ 1193d3b0591SJens Wiklander /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ 1203d3b0591SJens Wiklander #if defined(__GNUC__) && \ 1213d3b0591SJens Wiklander ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ 1223d3b0591SJens Wiklander __ARM_ARCH >= 6 1233d3b0591SJens Wiklander static inline uint32_t aria_p3( uint32_t x ) 1243d3b0591SJens Wiklander { 1253d3b0591SJens Wiklander uint32_t r; 1263d3b0591SJens Wiklander __asm( "rev %0, %1" : "=l" (r) : "l" (x) ); 1273d3b0591SJens Wiklander return( r ); 1283d3b0591SJens Wiklander } 1293d3b0591SJens Wiklander #define ARIA_P3 aria_p3 1303d3b0591SJens Wiklander #elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ 1313d3b0591SJens Wiklander ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) 1323d3b0591SJens Wiklander static inline uint32_t aria_p3( uint32_t x ) 1333d3b0591SJens Wiklander { 1343d3b0591SJens Wiklander uint32_t r; 1353d3b0591SJens Wiklander __asm( "rev r, x" ); 1363d3b0591SJens Wiklander return( r ); 1373d3b0591SJens Wiklander } 1383d3b0591SJens Wiklander #define ARIA_P3 aria_p3 1393d3b0591SJens Wiklander #endif 1403d3b0591SJens Wiklander #endif /* arm */ 1413d3b0591SJens Wiklander #if defined(__GNUC__) && \ 1423d3b0591SJens Wiklander defined(__i386__) || defined(__amd64__) || defined( __x86_64__) 1433d3b0591SJens Wiklander static inline uint32_t aria_p3( uint32_t x ) 1443d3b0591SJens Wiklander { 1453d3b0591SJens Wiklander __asm( "bswap %0" : "=r" (x) : "0" (x) ); 1463d3b0591SJens Wiklander return( x ); 1473d3b0591SJens Wiklander } 1483d3b0591SJens Wiklander #define ARIA_P3 aria_p3 1493d3b0591SJens Wiklander #endif /* x86 gnuc */ 1503d3b0591SJens Wiklander #endif /* MBEDTLS_HAVE_ASM && GNUC */ 1513d3b0591SJens Wiklander #if !defined(ARIA_P3) 1523d3b0591SJens Wiklander #define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) ) 1533d3b0591SJens Wiklander #endif 1543d3b0591SJens Wiklander 1553d3b0591SJens Wiklander /* 1563d3b0591SJens Wiklander * ARIA Affine Transform 1573d3b0591SJens Wiklander * (a, b, c, d) = state in/out 1583d3b0591SJens Wiklander * 1593d3b0591SJens Wiklander * If we denote the first byte of input by 0, ..., the last byte by f, 1603d3b0591SJens Wiklander * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef. 1613d3b0591SJens Wiklander * 1623d3b0591SJens Wiklander * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple 1633d3b0591SJens Wiklander * rearrangements on adjacent pairs, output is: 1643d3b0591SJens Wiklander * 1653d3b0591SJens Wiklander * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe 1663d3b0591SJens Wiklander * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd 1673d3b0591SJens Wiklander * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd 1683d3b0591SJens Wiklander * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc 1693d3b0591SJens Wiklander * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe 1703d3b0591SJens Wiklander * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc 1713d3b0591SJens Wiklander * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef 1723d3b0591SJens Wiklander * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef 1733d3b0591SJens Wiklander * 1743d3b0591SJens Wiklander * Note: another presentation of the A transform can be found as the first 1753d3b0591SJens Wiklander * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4. 1763d3b0591SJens Wiklander * The implementation below uses only P1 and P2 as they are sufficient. 1773d3b0591SJens Wiklander */ 1783d3b0591SJens Wiklander static inline void aria_a( uint32_t *a, uint32_t *b, 1793d3b0591SJens Wiklander uint32_t *c, uint32_t *d ) 1803d3b0591SJens Wiklander { 1813d3b0591SJens Wiklander uint32_t ta, tb, tc; 1823d3b0591SJens Wiklander ta = *b; // 4567 1833d3b0591SJens Wiklander *b = *a; // 0123 1843d3b0591SJens Wiklander *a = ARIA_P2( ta ); // 6745 1853d3b0591SJens Wiklander tb = ARIA_P2( *d ); // efcd 1863d3b0591SJens Wiklander *d = ARIA_P1( *c ); // 98ba 1873d3b0591SJens Wiklander *c = ARIA_P1( tb ); // fedc 1883d3b0591SJens Wiklander ta ^= *d; // 4567+98ba 1893d3b0591SJens Wiklander tc = ARIA_P2( *b ); // 2301 1903d3b0591SJens Wiklander ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc 1913d3b0591SJens Wiklander tb ^= ARIA_P2( *d ); // ba98+efcd 1923d3b0591SJens Wiklander tc ^= ARIA_P1( *a ); // 2301+7654 1933d3b0591SJens Wiklander *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT 1943d3b0591SJens Wiklander tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc 1953d3b0591SJens Wiklander *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT 1963d3b0591SJens Wiklander ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe 1973d3b0591SJens Wiklander *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT 1983d3b0591SJens Wiklander tc = ARIA_P2( tc ); // 0123+5476 1993d3b0591SJens Wiklander *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT 2003d3b0591SJens Wiklander } 2013d3b0591SJens Wiklander 2023d3b0591SJens Wiklander /* 2033d3b0591SJens Wiklander * ARIA Substitution Layer SL1 / SL2 2043d3b0591SJens Wiklander * (a, b, c, d) = state in/out 2053d3b0591SJens Wiklander * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below) 2063d3b0591SJens Wiklander * 2073d3b0591SJens Wiklander * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1 2083d3b0591SJens Wiklander * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2 2093d3b0591SJens Wiklander */ 2103d3b0591SJens Wiklander static inline void aria_sl( uint32_t *a, uint32_t *b, 2113d3b0591SJens Wiklander uint32_t *c, uint32_t *d, 2123d3b0591SJens Wiklander const uint8_t sa[256], const uint8_t sb[256], 2133d3b0591SJens Wiklander const uint8_t sc[256], const uint8_t sd[256] ) 2143d3b0591SJens Wiklander { 215*039e02dfSJerome Forissier *a = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *a ) ] ) ^ 216*039e02dfSJerome Forissier (((uint32_t) sb[ MBEDTLS_BYTE_1( *a ) ]) << 8) ^ 217*039e02dfSJerome Forissier (((uint32_t) sc[ MBEDTLS_BYTE_2( *a ) ]) << 16) ^ 218*039e02dfSJerome Forissier (((uint32_t) sd[ MBEDTLS_BYTE_3( *a ) ]) << 24); 219*039e02dfSJerome Forissier *b = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *b ) ] ) ^ 220*039e02dfSJerome Forissier (((uint32_t) sb[ MBEDTLS_BYTE_1( *b ) ]) << 8) ^ 221*039e02dfSJerome Forissier (((uint32_t) sc[ MBEDTLS_BYTE_2( *b ) ]) << 16) ^ 222*039e02dfSJerome Forissier (((uint32_t) sd[ MBEDTLS_BYTE_3( *b ) ]) << 24); 223*039e02dfSJerome Forissier *c = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *c ) ] ) ^ 224*039e02dfSJerome Forissier (((uint32_t) sb[ MBEDTLS_BYTE_1( *c ) ]) << 8) ^ 225*039e02dfSJerome Forissier (((uint32_t) sc[ MBEDTLS_BYTE_2( *c ) ]) << 16) ^ 226*039e02dfSJerome Forissier (((uint32_t) sd[ MBEDTLS_BYTE_3( *c ) ]) << 24); 227*039e02dfSJerome Forissier *d = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *d ) ] ) ^ 228*039e02dfSJerome Forissier (((uint32_t) sb[ MBEDTLS_BYTE_1( *d ) ]) << 8) ^ 229*039e02dfSJerome Forissier (((uint32_t) sc[ MBEDTLS_BYTE_2( *d ) ]) << 16) ^ 230*039e02dfSJerome Forissier (((uint32_t) sd[ MBEDTLS_BYTE_3( *d ) ]) << 24); 2313d3b0591SJens Wiklander } 2323d3b0591SJens Wiklander 2333d3b0591SJens Wiklander /* 2343d3b0591SJens Wiklander * S-Boxes 2353d3b0591SJens Wiklander */ 2363d3b0591SJens Wiklander static const uint8_t aria_sb1[256] = 2373d3b0591SJens Wiklander { 2383d3b0591SJens Wiklander 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 2393d3b0591SJens Wiklander 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 2403d3b0591SJens Wiklander 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 2413d3b0591SJens Wiklander 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 2423d3b0591SJens Wiklander 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 2433d3b0591SJens Wiklander 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 2443d3b0591SJens Wiklander 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 2453d3b0591SJens Wiklander 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 2463d3b0591SJens Wiklander 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 2473d3b0591SJens Wiklander 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 2483d3b0591SJens Wiklander 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 2493d3b0591SJens Wiklander 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 2503d3b0591SJens Wiklander 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 2513d3b0591SJens Wiklander 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 2523d3b0591SJens Wiklander 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 2533d3b0591SJens Wiklander 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 2543d3b0591SJens Wiklander 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 2553d3b0591SJens Wiklander 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 2563d3b0591SJens Wiklander 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 2573d3b0591SJens Wiklander 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 2583d3b0591SJens Wiklander 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 2593d3b0591SJens Wiklander 0xB0, 0x54, 0xBB, 0x16 2603d3b0591SJens Wiklander }; 2613d3b0591SJens Wiklander 2623d3b0591SJens Wiklander static const uint8_t aria_sb2[256] = 2633d3b0591SJens Wiklander { 2643d3b0591SJens Wiklander 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, 2653d3b0591SJens Wiklander 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, 2663d3b0591SJens Wiklander 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B, 2673d3b0591SJens Wiklander 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB, 2683d3b0591SJens Wiklander 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, 2693d3b0591SJens Wiklander 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, 2703d3b0591SJens Wiklander 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, 2713d3b0591SJens Wiklander 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, 2723d3b0591SJens Wiklander 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, 2733d3b0591SJens Wiklander 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, 2743d3b0591SJens Wiklander 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD, 2753d3b0591SJens Wiklander 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC, 2763d3b0591SJens Wiklander 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, 2773d3b0591SJens Wiklander 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, 2783d3b0591SJens Wiklander 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5, 2793d3b0591SJens Wiklander 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8, 2803d3b0591SJens Wiklander 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, 2813d3b0591SJens Wiklander 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, 2823d3b0591SJens Wiklander 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, 2833d3b0591SJens Wiklander 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, 2843d3b0591SJens Wiklander 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, 2853d3b0591SJens Wiklander 0xAF, 0xBA, 0xB5, 0x81 2863d3b0591SJens Wiklander }; 2873d3b0591SJens Wiklander 2883d3b0591SJens Wiklander static const uint8_t aria_is1[256] = 2893d3b0591SJens Wiklander { 2903d3b0591SJens Wiklander 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 2913d3b0591SJens Wiklander 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 2923d3b0591SJens Wiklander 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 2933d3b0591SJens Wiklander 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 2943d3b0591SJens Wiklander 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 2953d3b0591SJens Wiklander 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 2963d3b0591SJens Wiklander 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 2973d3b0591SJens Wiklander 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 2983d3b0591SJens Wiklander 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 2993d3b0591SJens Wiklander 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 3003d3b0591SJens Wiklander 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, 3013d3b0591SJens Wiklander 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 3023d3b0591SJens Wiklander 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 3033d3b0591SJens Wiklander 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 3043d3b0591SJens Wiklander 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 3053d3b0591SJens Wiklander 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 3063d3b0591SJens Wiklander 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 3073d3b0591SJens Wiklander 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 3083d3b0591SJens Wiklander 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 3093d3b0591SJens Wiklander 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 3103d3b0591SJens Wiklander 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 3113d3b0591SJens Wiklander 0x55, 0x21, 0x0C, 0x7D 3123d3b0591SJens Wiklander }; 3133d3b0591SJens Wiklander 3143d3b0591SJens Wiklander static const uint8_t aria_is2[256] = 3153d3b0591SJens Wiklander { 3163d3b0591SJens Wiklander 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, 3173d3b0591SJens Wiklander 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, 3183d3b0591SJens Wiklander 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89, 3193d3b0591SJens Wiklander 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D, 3203d3b0591SJens Wiklander 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, 3213d3b0591SJens Wiklander 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, 3223d3b0591SJens Wiklander 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, 3233d3b0591SJens Wiklander 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, 3243d3b0591SJens Wiklander 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, 3253d3b0591SJens Wiklander 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, 3263d3b0591SJens Wiklander 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55, 3273d3b0591SJens Wiklander 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A, 3283d3b0591SJens Wiklander 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, 3293d3b0591SJens Wiklander 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, 3303d3b0591SJens Wiklander 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6, 3313d3b0591SJens Wiklander 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5, 3323d3b0591SJens Wiklander 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, 3333d3b0591SJens Wiklander 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, 3343d3b0591SJens Wiklander 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, 3353d3b0591SJens Wiklander 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, 3363d3b0591SJens Wiklander 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, 3373d3b0591SJens Wiklander 0x03, 0xA2, 0xAC, 0x60 3383d3b0591SJens Wiklander }; 3393d3b0591SJens Wiklander 3403d3b0591SJens Wiklander /* 3413d3b0591SJens Wiklander * Helper for key schedule: r = FO( p, k ) ^ x 3423d3b0591SJens Wiklander */ 3433d3b0591SJens Wiklander static void aria_fo_xor( uint32_t r[4], const uint32_t p[4], 3443d3b0591SJens Wiklander const uint32_t k[4], const uint32_t x[4] ) 3453d3b0591SJens Wiklander { 3463d3b0591SJens Wiklander uint32_t a, b, c, d; 3473d3b0591SJens Wiklander 3483d3b0591SJens Wiklander a = p[0] ^ k[0]; 3493d3b0591SJens Wiklander b = p[1] ^ k[1]; 3503d3b0591SJens Wiklander c = p[2] ^ k[2]; 3513d3b0591SJens Wiklander d = p[3] ^ k[3]; 3523d3b0591SJens Wiklander 3533d3b0591SJens Wiklander aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); 3543d3b0591SJens Wiklander aria_a( &a, &b, &c, &d ); 3553d3b0591SJens Wiklander 3563d3b0591SJens Wiklander r[0] = a ^ x[0]; 3573d3b0591SJens Wiklander r[1] = b ^ x[1]; 3583d3b0591SJens Wiklander r[2] = c ^ x[2]; 3593d3b0591SJens Wiklander r[3] = d ^ x[3]; 3603d3b0591SJens Wiklander } 3613d3b0591SJens Wiklander 3623d3b0591SJens Wiklander /* 3633d3b0591SJens Wiklander * Helper for key schedule: r = FE( p, k ) ^ x 3643d3b0591SJens Wiklander */ 3653d3b0591SJens Wiklander static void aria_fe_xor( uint32_t r[4], const uint32_t p[4], 3663d3b0591SJens Wiklander const uint32_t k[4], const uint32_t x[4] ) 3673d3b0591SJens Wiklander { 3683d3b0591SJens Wiklander uint32_t a, b, c, d; 3693d3b0591SJens Wiklander 3703d3b0591SJens Wiklander a = p[0] ^ k[0]; 3713d3b0591SJens Wiklander b = p[1] ^ k[1]; 3723d3b0591SJens Wiklander c = p[2] ^ k[2]; 3733d3b0591SJens Wiklander d = p[3] ^ k[3]; 3743d3b0591SJens Wiklander 3753d3b0591SJens Wiklander aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); 3763d3b0591SJens Wiklander aria_a( &a, &b, &c, &d ); 3773d3b0591SJens Wiklander 3783d3b0591SJens Wiklander r[0] = a ^ x[0]; 3793d3b0591SJens Wiklander r[1] = b ^ x[1]; 3803d3b0591SJens Wiklander r[2] = c ^ x[2]; 3813d3b0591SJens Wiklander r[3] = d ^ x[3]; 3823d3b0591SJens Wiklander } 3833d3b0591SJens Wiklander 3843d3b0591SJens Wiklander /* 3853d3b0591SJens Wiklander * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup. 3863d3b0591SJens Wiklander * 3873d3b0591SJens Wiklander * We chose to store bytes into 32-bit words in little-endian format (see 388*039e02dfSJerome Forissier * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse 389*039e02dfSJerome Forissier * bytes here. 3903d3b0591SJens Wiklander */ 3913d3b0591SJens Wiklander static void aria_rot128( uint32_t r[4], const uint32_t a[4], 3923d3b0591SJens Wiklander const uint32_t b[4], uint8_t n ) 3933d3b0591SJens Wiklander { 3943d3b0591SJens Wiklander uint8_t i, j; 3953d3b0591SJens Wiklander uint32_t t, u; 3963d3b0591SJens Wiklander 3973d3b0591SJens Wiklander const uint8_t n1 = n % 32; // bit offset 3983d3b0591SJens Wiklander const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset 3993d3b0591SJens Wiklander 4003d3b0591SJens Wiklander j = ( n / 32 ) % 4; // initial word offset 4013d3b0591SJens Wiklander t = ARIA_P3( b[j] ); // big endian 4023d3b0591SJens Wiklander for( i = 0; i < 4; i++ ) 4033d3b0591SJens Wiklander { 4043d3b0591SJens Wiklander j = ( j + 1 ) % 4; // get next word, big endian 4053d3b0591SJens Wiklander u = ARIA_P3( b[j] ); 4063d3b0591SJens Wiklander t <<= n1; // rotate 4073d3b0591SJens Wiklander t |= u >> n2; 4083d3b0591SJens Wiklander t = ARIA_P3( t ); // back to little endian 4093d3b0591SJens Wiklander r[i] = a[i] ^ t; // store 4103d3b0591SJens Wiklander t = u; // move to next word 4113d3b0591SJens Wiklander } 4123d3b0591SJens Wiklander } 4133d3b0591SJens Wiklander 4143d3b0591SJens Wiklander /* 4153d3b0591SJens Wiklander * Set encryption key 4163d3b0591SJens Wiklander */ 4173d3b0591SJens Wiklander int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, 4183d3b0591SJens Wiklander const unsigned char *key, unsigned int keybits ) 4193d3b0591SJens Wiklander { 4203d3b0591SJens Wiklander /* round constant masks */ 4213d3b0591SJens Wiklander const uint32_t rc[3][4] = 4223d3b0591SJens Wiklander { 4233d3b0591SJens Wiklander { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA }, 4243d3b0591SJens Wiklander { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF }, 4253d3b0591SJens Wiklander { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 } 4263d3b0591SJens Wiklander }; 4273d3b0591SJens Wiklander 4283d3b0591SJens Wiklander int i; 4293d3b0591SJens Wiklander uint32_t w[4][4], *w2; 4303d3b0591SJens Wiklander ARIA_VALIDATE_RET( ctx != NULL ); 4313d3b0591SJens Wiklander ARIA_VALIDATE_RET( key != NULL ); 4323d3b0591SJens Wiklander 4333d3b0591SJens Wiklander if( keybits != 128 && keybits != 192 && keybits != 256 ) 4343d3b0591SJens Wiklander return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); 4353d3b0591SJens Wiklander 4363d3b0591SJens Wiklander /* Copy key to W0 (and potential remainder to W1) */ 437*039e02dfSJerome Forissier w[0][0] = MBEDTLS_GET_UINT32_LE( key, 0 ); 438*039e02dfSJerome Forissier w[0][1] = MBEDTLS_GET_UINT32_LE( key, 4 ); 439*039e02dfSJerome Forissier w[0][2] = MBEDTLS_GET_UINT32_LE( key, 8 ); 440*039e02dfSJerome Forissier w[0][3] = MBEDTLS_GET_UINT32_LE( key, 12 ); 4413d3b0591SJens Wiklander 4423d3b0591SJens Wiklander memset( w[1], 0, 16 ); 4433d3b0591SJens Wiklander if( keybits >= 192 ) 4443d3b0591SJens Wiklander { 445*039e02dfSJerome Forissier w[1][0] = MBEDTLS_GET_UINT32_LE( key, 16 ); // 192 bit key 446*039e02dfSJerome Forissier w[1][1] = MBEDTLS_GET_UINT32_LE( key, 20 ); 4473d3b0591SJens Wiklander } 4483d3b0591SJens Wiklander if( keybits == 256 ) 4493d3b0591SJens Wiklander { 450*039e02dfSJerome Forissier w[1][2] = MBEDTLS_GET_UINT32_LE( key, 24 ); // 256 bit key 451*039e02dfSJerome Forissier w[1][3] = MBEDTLS_GET_UINT32_LE( key, 28 ); 4523d3b0591SJens Wiklander } 4533d3b0591SJens Wiklander 4543d3b0591SJens Wiklander i = ( keybits - 128 ) >> 6; // index: 0, 1, 2 4553d3b0591SJens Wiklander ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16 4563d3b0591SJens Wiklander 4573d3b0591SJens Wiklander aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR 4583d3b0591SJens Wiklander i = i < 2 ? i + 1 : 0; 4593d3b0591SJens Wiklander aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0 4603d3b0591SJens Wiklander i = i < 2 ? i + 1 : 0; 4613d3b0591SJens Wiklander aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1 4623d3b0591SJens Wiklander 4633d3b0591SJens Wiklander for( i = 0; i < 4; i++ ) // create round keys 4643d3b0591SJens Wiklander { 4653d3b0591SJens Wiklander w2 = w[(i + 1) & 3]; 4663d3b0591SJens Wiklander aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 ); 4673d3b0591SJens Wiklander aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 ); 4683d3b0591SJens Wiklander aria_rot128( ctx->rk[i + 8], w[i], w2, 61 ); 4693d3b0591SJens Wiklander aria_rot128( ctx->rk[i + 12], w[i], w2, 31 ); 4703d3b0591SJens Wiklander } 4713d3b0591SJens Wiklander aria_rot128( ctx->rk[16], w[0], w[1], 19 ); 4723d3b0591SJens Wiklander 4733d3b0591SJens Wiklander /* w holds enough info to reconstruct the round keys */ 4743d3b0591SJens Wiklander mbedtls_platform_zeroize( w, sizeof( w ) ); 4753d3b0591SJens Wiklander 4763d3b0591SJens Wiklander return( 0 ); 4773d3b0591SJens Wiklander } 4783d3b0591SJens Wiklander 4793d3b0591SJens Wiklander /* 4803d3b0591SJens Wiklander * Set decryption key 4813d3b0591SJens Wiklander */ 4823d3b0591SJens Wiklander int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, 4833d3b0591SJens Wiklander const unsigned char *key, unsigned int keybits ) 4843d3b0591SJens Wiklander { 4853d3b0591SJens Wiklander int i, j, k, ret; 4863d3b0591SJens Wiklander ARIA_VALIDATE_RET( ctx != NULL ); 4873d3b0591SJens Wiklander ARIA_VALIDATE_RET( key != NULL ); 4883d3b0591SJens Wiklander 4893d3b0591SJens Wiklander ret = mbedtls_aria_setkey_enc( ctx, key, keybits ); 4903d3b0591SJens Wiklander if( ret != 0 ) 4913d3b0591SJens Wiklander return( ret ); 4923d3b0591SJens Wiklander 4933d3b0591SJens Wiklander /* flip the order of round keys */ 4943d3b0591SJens Wiklander for( i = 0, j = ctx->nr; i < j; i++, j-- ) 4953d3b0591SJens Wiklander { 4963d3b0591SJens Wiklander for( k = 0; k < 4; k++ ) 4973d3b0591SJens Wiklander { 4983d3b0591SJens Wiklander uint32_t t = ctx->rk[i][k]; 4993d3b0591SJens Wiklander ctx->rk[i][k] = ctx->rk[j][k]; 5003d3b0591SJens Wiklander ctx->rk[j][k] = t; 5013d3b0591SJens Wiklander } 5023d3b0591SJens Wiklander } 5033d3b0591SJens Wiklander 5043d3b0591SJens Wiklander /* apply affine transform to middle keys */ 5053d3b0591SJens Wiklander for( i = 1; i < ctx->nr; i++ ) 5063d3b0591SJens Wiklander { 5073d3b0591SJens Wiklander aria_a( &ctx->rk[i][0], &ctx->rk[i][1], 5083d3b0591SJens Wiklander &ctx->rk[i][2], &ctx->rk[i][3] ); 5093d3b0591SJens Wiklander } 5103d3b0591SJens Wiklander 5113d3b0591SJens Wiklander return( 0 ); 5123d3b0591SJens Wiklander } 5133d3b0591SJens Wiklander 5143d3b0591SJens Wiklander /* 5153d3b0591SJens Wiklander * Encrypt a block 5163d3b0591SJens Wiklander */ 5173d3b0591SJens Wiklander int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, 5183d3b0591SJens Wiklander const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], 5193d3b0591SJens Wiklander unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ) 5203d3b0591SJens Wiklander { 5213d3b0591SJens Wiklander int i; 5223d3b0591SJens Wiklander 5233d3b0591SJens Wiklander uint32_t a, b, c, d; 5243d3b0591SJens Wiklander ARIA_VALIDATE_RET( ctx != NULL ); 5253d3b0591SJens Wiklander ARIA_VALIDATE_RET( input != NULL ); 5263d3b0591SJens Wiklander ARIA_VALIDATE_RET( output != NULL ); 5273d3b0591SJens Wiklander 528*039e02dfSJerome Forissier a = MBEDTLS_GET_UINT32_LE( input, 0 ); 529*039e02dfSJerome Forissier b = MBEDTLS_GET_UINT32_LE( input, 4 ); 530*039e02dfSJerome Forissier c = MBEDTLS_GET_UINT32_LE( input, 8 ); 531*039e02dfSJerome Forissier d = MBEDTLS_GET_UINT32_LE( input, 12 ); 5323d3b0591SJens Wiklander 5333d3b0591SJens Wiklander i = 0; 5343d3b0591SJens Wiklander while( 1 ) 5353d3b0591SJens Wiklander { 5363d3b0591SJens Wiklander a ^= ctx->rk[i][0]; 5373d3b0591SJens Wiklander b ^= ctx->rk[i][1]; 5383d3b0591SJens Wiklander c ^= ctx->rk[i][2]; 5393d3b0591SJens Wiklander d ^= ctx->rk[i][3]; 5403d3b0591SJens Wiklander i++; 5413d3b0591SJens Wiklander 5423d3b0591SJens Wiklander aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); 5433d3b0591SJens Wiklander aria_a( &a, &b, &c, &d ); 5443d3b0591SJens Wiklander 5453d3b0591SJens Wiklander a ^= ctx->rk[i][0]; 5463d3b0591SJens Wiklander b ^= ctx->rk[i][1]; 5473d3b0591SJens Wiklander c ^= ctx->rk[i][2]; 5483d3b0591SJens Wiklander d ^= ctx->rk[i][3]; 5493d3b0591SJens Wiklander i++; 5503d3b0591SJens Wiklander 5513d3b0591SJens Wiklander aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); 5523d3b0591SJens Wiklander if( i >= ctx->nr ) 5533d3b0591SJens Wiklander break; 5543d3b0591SJens Wiklander aria_a( &a, &b, &c, &d ); 5553d3b0591SJens Wiklander } 5563d3b0591SJens Wiklander 5573d3b0591SJens Wiklander /* final key mixing */ 5583d3b0591SJens Wiklander a ^= ctx->rk[i][0]; 5593d3b0591SJens Wiklander b ^= ctx->rk[i][1]; 5603d3b0591SJens Wiklander c ^= ctx->rk[i][2]; 5613d3b0591SJens Wiklander d ^= ctx->rk[i][3]; 5623d3b0591SJens Wiklander 563*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( a, output, 0 ); 564*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( b, output, 4 ); 565*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( c, output, 8 ); 566*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( d, output, 12 ); 5673d3b0591SJens Wiklander 5683d3b0591SJens Wiklander return( 0 ); 5693d3b0591SJens Wiklander } 5703d3b0591SJens Wiklander 5713d3b0591SJens Wiklander /* Initialize context */ 5723d3b0591SJens Wiklander void mbedtls_aria_init( mbedtls_aria_context *ctx ) 5733d3b0591SJens Wiklander { 5743d3b0591SJens Wiklander ARIA_VALIDATE( ctx != NULL ); 5753d3b0591SJens Wiklander memset( ctx, 0, sizeof( mbedtls_aria_context ) ); 5763d3b0591SJens Wiklander } 5773d3b0591SJens Wiklander 5783d3b0591SJens Wiklander /* Clear context */ 5793d3b0591SJens Wiklander void mbedtls_aria_free( mbedtls_aria_context *ctx ) 5803d3b0591SJens Wiklander { 5813d3b0591SJens Wiklander if( ctx == NULL ) 5823d3b0591SJens Wiklander return; 5833d3b0591SJens Wiklander 5843d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) ); 5853d3b0591SJens Wiklander } 5863d3b0591SJens Wiklander 5873d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC) 5883d3b0591SJens Wiklander /* 5893d3b0591SJens Wiklander * ARIA-CBC buffer encryption/decryption 5903d3b0591SJens Wiklander */ 5913d3b0591SJens Wiklander int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, 5923d3b0591SJens Wiklander int mode, 5933d3b0591SJens Wiklander size_t length, 5943d3b0591SJens Wiklander unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], 5953d3b0591SJens Wiklander const unsigned char *input, 5963d3b0591SJens Wiklander unsigned char *output ) 5973d3b0591SJens Wiklander { 5983d3b0591SJens Wiklander int i; 5993d3b0591SJens Wiklander unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; 6003d3b0591SJens Wiklander 6013d3b0591SJens Wiklander ARIA_VALIDATE_RET( ctx != NULL ); 6023d3b0591SJens Wiklander ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || 6033d3b0591SJens Wiklander mode == MBEDTLS_ARIA_DECRYPT ); 6043d3b0591SJens Wiklander ARIA_VALIDATE_RET( length == 0 || input != NULL ); 6053d3b0591SJens Wiklander ARIA_VALIDATE_RET( length == 0 || output != NULL ); 6063d3b0591SJens Wiklander ARIA_VALIDATE_RET( iv != NULL ); 6073d3b0591SJens Wiklander 6083d3b0591SJens Wiklander if( length % MBEDTLS_ARIA_BLOCKSIZE ) 6093d3b0591SJens Wiklander return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH ); 6103d3b0591SJens Wiklander 6113d3b0591SJens Wiklander if( mode == MBEDTLS_ARIA_DECRYPT ) 6123d3b0591SJens Wiklander { 6133d3b0591SJens Wiklander while( length > 0 ) 6143d3b0591SJens Wiklander { 6153d3b0591SJens Wiklander memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE ); 6163d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( ctx, input, output ); 6173d3b0591SJens Wiklander 6183d3b0591SJens Wiklander for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) 6193d3b0591SJens Wiklander output[i] = (unsigned char)( output[i] ^ iv[i] ); 6203d3b0591SJens Wiklander 6213d3b0591SJens Wiklander memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE ); 6223d3b0591SJens Wiklander 6233d3b0591SJens Wiklander input += MBEDTLS_ARIA_BLOCKSIZE; 6243d3b0591SJens Wiklander output += MBEDTLS_ARIA_BLOCKSIZE; 6253d3b0591SJens Wiklander length -= MBEDTLS_ARIA_BLOCKSIZE; 6263d3b0591SJens Wiklander } 6273d3b0591SJens Wiklander } 6283d3b0591SJens Wiklander else 6293d3b0591SJens Wiklander { 6303d3b0591SJens Wiklander while( length > 0 ) 6313d3b0591SJens Wiklander { 6323d3b0591SJens Wiklander for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) 6333d3b0591SJens Wiklander output[i] = (unsigned char)( input[i] ^ iv[i] ); 6343d3b0591SJens Wiklander 6353d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( ctx, output, output ); 6363d3b0591SJens Wiklander memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE ); 6373d3b0591SJens Wiklander 6383d3b0591SJens Wiklander input += MBEDTLS_ARIA_BLOCKSIZE; 6393d3b0591SJens Wiklander output += MBEDTLS_ARIA_BLOCKSIZE; 6403d3b0591SJens Wiklander length -= MBEDTLS_ARIA_BLOCKSIZE; 6413d3b0591SJens Wiklander } 6423d3b0591SJens Wiklander } 6433d3b0591SJens Wiklander 6443d3b0591SJens Wiklander return( 0 ); 6453d3b0591SJens Wiklander } 6463d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */ 6473d3b0591SJens Wiklander 6483d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB) 6493d3b0591SJens Wiklander /* 6503d3b0591SJens Wiklander * ARIA-CFB128 buffer encryption/decryption 6513d3b0591SJens Wiklander */ 6523d3b0591SJens Wiklander int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, 6533d3b0591SJens Wiklander int mode, 6543d3b0591SJens Wiklander size_t length, 6553d3b0591SJens Wiklander size_t *iv_off, 6563d3b0591SJens Wiklander unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], 6573d3b0591SJens Wiklander const unsigned char *input, 6583d3b0591SJens Wiklander unsigned char *output ) 6593d3b0591SJens Wiklander { 6603d3b0591SJens Wiklander unsigned char c; 6613d3b0591SJens Wiklander size_t n; 6623d3b0591SJens Wiklander 6633d3b0591SJens Wiklander ARIA_VALIDATE_RET( ctx != NULL ); 6643d3b0591SJens Wiklander ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || 6653d3b0591SJens Wiklander mode == MBEDTLS_ARIA_DECRYPT ); 6663d3b0591SJens Wiklander ARIA_VALIDATE_RET( length == 0 || input != NULL ); 6673d3b0591SJens Wiklander ARIA_VALIDATE_RET( length == 0 || output != NULL ); 6683d3b0591SJens Wiklander ARIA_VALIDATE_RET( iv != NULL ); 6693d3b0591SJens Wiklander ARIA_VALIDATE_RET( iv_off != NULL ); 6703d3b0591SJens Wiklander 6713d3b0591SJens Wiklander n = *iv_off; 6723d3b0591SJens Wiklander 6733d3b0591SJens Wiklander /* An overly large value of n can lead to an unlimited 6743d3b0591SJens Wiklander * buffer overflow. Therefore, guard against this 6753d3b0591SJens Wiklander * outside of parameter validation. */ 6763d3b0591SJens Wiklander if( n >= MBEDTLS_ARIA_BLOCKSIZE ) 6773d3b0591SJens Wiklander return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); 6783d3b0591SJens Wiklander 6793d3b0591SJens Wiklander if( mode == MBEDTLS_ARIA_DECRYPT ) 6803d3b0591SJens Wiklander { 6813d3b0591SJens Wiklander while( length-- ) 6823d3b0591SJens Wiklander { 6833d3b0591SJens Wiklander if( n == 0 ) 6843d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( ctx, iv, iv ); 6853d3b0591SJens Wiklander 6863d3b0591SJens Wiklander c = *input++; 6873d3b0591SJens Wiklander *output++ = c ^ iv[n]; 6883d3b0591SJens Wiklander iv[n] = c; 6893d3b0591SJens Wiklander 6903d3b0591SJens Wiklander n = ( n + 1 ) & 0x0F; 6913d3b0591SJens Wiklander } 6923d3b0591SJens Wiklander } 6933d3b0591SJens Wiklander else 6943d3b0591SJens Wiklander { 6953d3b0591SJens Wiklander while( length-- ) 6963d3b0591SJens Wiklander { 6973d3b0591SJens Wiklander if( n == 0 ) 6983d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( ctx, iv, iv ); 6993d3b0591SJens Wiklander 7003d3b0591SJens Wiklander iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); 7013d3b0591SJens Wiklander 7023d3b0591SJens Wiklander n = ( n + 1 ) & 0x0F; 7033d3b0591SJens Wiklander } 7043d3b0591SJens Wiklander } 7053d3b0591SJens Wiklander 7063d3b0591SJens Wiklander *iv_off = n; 7073d3b0591SJens Wiklander 7083d3b0591SJens Wiklander return( 0 ); 7093d3b0591SJens Wiklander } 7103d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */ 7113d3b0591SJens Wiklander 7123d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR) 7133d3b0591SJens Wiklander /* 7143d3b0591SJens Wiklander * ARIA-CTR buffer encryption/decryption 7153d3b0591SJens Wiklander */ 7163d3b0591SJens Wiklander int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, 7173d3b0591SJens Wiklander size_t length, 7183d3b0591SJens Wiklander size_t *nc_off, 7193d3b0591SJens Wiklander unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], 7203d3b0591SJens Wiklander unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], 7213d3b0591SJens Wiklander const unsigned char *input, 7223d3b0591SJens Wiklander unsigned char *output ) 7233d3b0591SJens Wiklander { 7243d3b0591SJens Wiklander int c, i; 7253d3b0591SJens Wiklander size_t n; 7263d3b0591SJens Wiklander 7273d3b0591SJens Wiklander ARIA_VALIDATE_RET( ctx != NULL ); 7283d3b0591SJens Wiklander ARIA_VALIDATE_RET( length == 0 || input != NULL ); 7293d3b0591SJens Wiklander ARIA_VALIDATE_RET( length == 0 || output != NULL ); 7303d3b0591SJens Wiklander ARIA_VALIDATE_RET( nonce_counter != NULL ); 7313d3b0591SJens Wiklander ARIA_VALIDATE_RET( stream_block != NULL ); 7323d3b0591SJens Wiklander ARIA_VALIDATE_RET( nc_off != NULL ); 7333d3b0591SJens Wiklander 7343d3b0591SJens Wiklander n = *nc_off; 7353d3b0591SJens Wiklander /* An overly large value of n can lead to an unlimited 7363d3b0591SJens Wiklander * buffer overflow. Therefore, guard against this 7373d3b0591SJens Wiklander * outside of parameter validation. */ 7383d3b0591SJens Wiklander if( n >= MBEDTLS_ARIA_BLOCKSIZE ) 7393d3b0591SJens Wiklander return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); 7403d3b0591SJens Wiklander 7413d3b0591SJens Wiklander while( length-- ) 7423d3b0591SJens Wiklander { 7433d3b0591SJens Wiklander if( n == 0 ) { 7443d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( ctx, nonce_counter, 7453d3b0591SJens Wiklander stream_block ); 7463d3b0591SJens Wiklander 7473d3b0591SJens Wiklander for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- ) 7483d3b0591SJens Wiklander if( ++nonce_counter[i - 1] != 0 ) 7493d3b0591SJens Wiklander break; 7503d3b0591SJens Wiklander } 7513d3b0591SJens Wiklander c = *input++; 7523d3b0591SJens Wiklander *output++ = (unsigned char)( c ^ stream_block[n] ); 7533d3b0591SJens Wiklander 7543d3b0591SJens Wiklander n = ( n + 1 ) & 0x0F; 7553d3b0591SJens Wiklander } 7563d3b0591SJens Wiklander 7573d3b0591SJens Wiklander *nc_off = n; 7583d3b0591SJens Wiklander 7593d3b0591SJens Wiklander return( 0 ); 7603d3b0591SJens Wiklander } 7613d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */ 7623d3b0591SJens Wiklander #endif /* !MBEDTLS_ARIA_ALT */ 7633d3b0591SJens Wiklander 7643d3b0591SJens Wiklander #if defined(MBEDTLS_SELF_TEST) 7653d3b0591SJens Wiklander 7663d3b0591SJens Wiklander /* 7673d3b0591SJens Wiklander * Basic ARIA ECB test vectors from RFC 5794 7683d3b0591SJens Wiklander */ 7693d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_key[32] = // test key 7703d3b0591SJens Wiklander { 7713d3b0591SJens Wiklander 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit 7723d3b0591SJens Wiklander 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 7733d3b0591SJens Wiklander 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit 7743d3b0591SJens Wiklander 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit 7753d3b0591SJens Wiklander }; 7763d3b0591SJens Wiklander 7773d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext 7783d3b0591SJens Wiklander { 7793d3b0591SJens Wiklander 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all 7803d3b0591SJens Wiklander 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes 7813d3b0591SJens Wiklander }; 7823d3b0591SJens Wiklander 7833d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext 7843d3b0591SJens Wiklander { 7853d3b0591SJens Wiklander { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit 7863d3b0591SJens Wiklander 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 }, 7873d3b0591SJens Wiklander { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit 7883d3b0591SJens Wiklander 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 }, 7893d3b0591SJens Wiklander { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit 7903d3b0591SJens Wiklander 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC } 7913d3b0591SJens Wiklander }; 7923d3b0591SJens Wiklander 7933d3b0591SJens Wiklander /* 7943d3b0591SJens Wiklander * Mode tests from "Test Vectors for ARIA" Version 1.0 7953d3b0591SJens Wiklander * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf 7963d3b0591SJens Wiklander */ 7973d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ 7983d3b0591SJens Wiklander defined(MBEDTLS_CIPHER_MODE_CTR)) 7993d3b0591SJens Wiklander static const uint8_t aria_test2_key[32] = 8003d3b0591SJens Wiklander { 8013d3b0591SJens Wiklander 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit 8023d3b0591SJens Wiklander 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 8033d3b0591SJens Wiklander 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit 8043d3b0591SJens Wiklander 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit 8053d3b0591SJens Wiklander }; 8063d3b0591SJens Wiklander 8073d3b0591SJens Wiklander static const uint8_t aria_test2_pt[48] = 8083d3b0591SJens Wiklander { 8093d3b0591SJens Wiklander 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all 8103d3b0591SJens Wiklander 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb, 8113d3b0591SJens Wiklander 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, 8123d3b0591SJens Wiklander 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, 8133d3b0591SJens Wiklander 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa, 8143d3b0591SJens Wiklander 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb, 8153d3b0591SJens Wiklander }; 8163d3b0591SJens Wiklander #endif 8173d3b0591SJens Wiklander 8183d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)) 8193d3b0591SJens Wiklander static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] = 8203d3b0591SJens Wiklander { 8213d3b0591SJens Wiklander 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB 8223d3b0591SJens Wiklander 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV 8233d3b0591SJens Wiklander }; 8243d3b0591SJens Wiklander #endif 8253d3b0591SJens Wiklander 8263d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC) 8273d3b0591SJens Wiklander static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext 8283d3b0591SJens Wiklander { 8293d3b0591SJens Wiklander { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key 8303d3b0591SJens Wiklander 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34, 8313d3b0591SJens Wiklander 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64, 8323d3b0591SJens Wiklander 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38, 8333d3b0591SJens Wiklander 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c, 8343d3b0591SJens Wiklander 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 }, 8353d3b0591SJens Wiklander { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key 8363d3b0591SJens Wiklander 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f, 8373d3b0591SJens Wiklander 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1, 8383d3b0591SJens Wiklander 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5, 8393d3b0591SJens Wiklander 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92, 8403d3b0591SJens Wiklander 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e }, 8413d3b0591SJens Wiklander { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key 8423d3b0591SJens Wiklander 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab, 8433d3b0591SJens Wiklander 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef, 8443d3b0591SJens Wiklander 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52, 8453d3b0591SJens Wiklander 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5, 8463d3b0591SJens Wiklander 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b } 8473d3b0591SJens Wiklander }; 8483d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */ 8493d3b0591SJens Wiklander 8503d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB) 8513d3b0591SJens Wiklander static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext 8523d3b0591SJens Wiklander { 8533d3b0591SJens Wiklander { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key 8543d3b0591SJens Wiklander 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00, 8553d3b0591SJens Wiklander 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a, 8563d3b0591SJens Wiklander 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01, 8573d3b0591SJens Wiklander 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96, 8583d3b0591SJens Wiklander 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b }, 8593d3b0591SJens Wiklander { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key 8603d3b0591SJens Wiklander 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c, 8613d3b0591SJens Wiklander 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94, 8623d3b0591SJens Wiklander 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59, 8633d3b0591SJens Wiklander 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86, 8643d3b0591SJens Wiklander 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b }, 8653d3b0591SJens Wiklander { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key 8663d3b0591SJens Wiklander 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35, 8673d3b0591SJens Wiklander 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70, 8683d3b0591SJens Wiklander 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa, 8693d3b0591SJens Wiklander 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c, 8703d3b0591SJens Wiklander 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 } 8713d3b0591SJens Wiklander }; 8723d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */ 8733d3b0591SJens Wiklander 8743d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR) 8753d3b0591SJens Wiklander static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext 8763d3b0591SJens Wiklander { 8773d3b0591SJens Wiklander { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key 8783d3b0591SJens Wiklander 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1, 8793d3b0591SJens Wiklander 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1, 8803d3b0591SJens Wiklander 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f, 8813d3b0591SJens Wiklander 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71, 8823d3b0591SJens Wiklander 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 }, 8833d3b0591SJens Wiklander { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key 8843d3b0591SJens Wiklander 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce, 8853d3b0591SJens Wiklander 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde, 8863d3b0591SJens Wiklander 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79, 8873d3b0591SJens Wiklander 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce, 8883d3b0591SJens Wiklander 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf }, 8893d3b0591SJens Wiklander { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key 8903d3b0591SJens Wiklander 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2, 8913d3b0591SJens Wiklander 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89, 8923d3b0591SJens Wiklander 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f, 8933d3b0591SJens Wiklander 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7, 8943d3b0591SJens Wiklander 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 } 8953d3b0591SJens Wiklander }; 8963d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */ 8973d3b0591SJens Wiklander 8983d3b0591SJens Wiklander #define ARIA_SELF_TEST_IF_FAIL \ 8993d3b0591SJens Wiklander { \ 9003d3b0591SJens Wiklander if( verbose ) \ 9013d3b0591SJens Wiklander mbedtls_printf( "failed\n" ); \ 9027901324dSJerome Forissier goto exit; \ 9033d3b0591SJens Wiklander } else { \ 9043d3b0591SJens Wiklander if( verbose ) \ 9053d3b0591SJens Wiklander mbedtls_printf( "passed\n" ); \ 9063d3b0591SJens Wiklander } 9073d3b0591SJens Wiklander 9083d3b0591SJens Wiklander /* 9093d3b0591SJens Wiklander * Checkup routine 9103d3b0591SJens Wiklander */ 9113d3b0591SJens Wiklander int mbedtls_aria_self_test( int verbose ) 9123d3b0591SJens Wiklander { 9133d3b0591SJens Wiklander int i; 9143d3b0591SJens Wiklander uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; 9153d3b0591SJens Wiklander mbedtls_aria_context ctx; 9167901324dSJerome Forissier int ret = 1; 9173d3b0591SJens Wiklander 9183d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) 9193d3b0591SJens Wiklander size_t j; 9203d3b0591SJens Wiklander #endif 9213d3b0591SJens Wiklander 9223d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || \ 9233d3b0591SJens Wiklander defined(MBEDTLS_CIPHER_MODE_CFB) || \ 9243d3b0591SJens Wiklander defined(MBEDTLS_CIPHER_MODE_CTR)) 9253d3b0591SJens Wiklander uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; 9263d3b0591SJens Wiklander #endif 9273d3b0591SJens Wiklander 9287901324dSJerome Forissier mbedtls_aria_init( &ctx ); 9297901324dSJerome Forissier 9303d3b0591SJens Wiklander /* 9313d3b0591SJens Wiklander * Test set 1 9323d3b0591SJens Wiklander */ 9333d3b0591SJens Wiklander for( i = 0; i < 3; i++ ) 9343d3b0591SJens Wiklander { 9353d3b0591SJens Wiklander /* test ECB encryption */ 9363d3b0591SJens Wiklander if( verbose ) 9373d3b0591SJens Wiklander mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i ); 9383d3b0591SJens Wiklander mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i ); 9393d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk ); 9403d3b0591SJens Wiklander if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) 9413d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 9423d3b0591SJens Wiklander 9433d3b0591SJens Wiklander /* test ECB decryption */ 9443d3b0591SJens Wiklander if( verbose ) 9453d3b0591SJens Wiklander mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i ); 9463d3b0591SJens Wiklander mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i ); 9473d3b0591SJens Wiklander mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk ); 9483d3b0591SJens Wiklander if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) 9493d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 9503d3b0591SJens Wiklander } 9513d3b0591SJens Wiklander if( verbose ) 9523d3b0591SJens Wiklander mbedtls_printf( "\n" ); 9533d3b0591SJens Wiklander 9543d3b0591SJens Wiklander /* 9553d3b0591SJens Wiklander * Test set 2 9563d3b0591SJens Wiklander */ 9573d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC) 9583d3b0591SJens Wiklander for( i = 0; i < 3; i++ ) 9593d3b0591SJens Wiklander { 9603d3b0591SJens Wiklander /* Test CBC encryption */ 9613d3b0591SJens Wiklander if( verbose ) 9623d3b0591SJens Wiklander mbedtls_printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i ); 9633d3b0591SJens Wiklander mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); 9643d3b0591SJens Wiklander memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); 9653d3b0591SJens Wiklander memset( buf, 0x55, sizeof( buf ) ); 9663d3b0591SJens Wiklander mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, 9673d3b0591SJens Wiklander aria_test2_pt, buf ); 9683d3b0591SJens Wiklander if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 ) 9693d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 9703d3b0591SJens Wiklander 9713d3b0591SJens Wiklander /* Test CBC decryption */ 9723d3b0591SJens Wiklander if( verbose ) 9733d3b0591SJens Wiklander mbedtls_printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i ); 9743d3b0591SJens Wiklander mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i ); 9753d3b0591SJens Wiklander memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); 9763d3b0591SJens Wiklander memset( buf, 0xAA, sizeof( buf ) ); 9773d3b0591SJens Wiklander mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, 9783d3b0591SJens Wiklander aria_test2_cbc_ct[i], buf ); 9793d3b0591SJens Wiklander if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) 9803d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 9813d3b0591SJens Wiklander } 9823d3b0591SJens Wiklander if( verbose ) 9833d3b0591SJens Wiklander mbedtls_printf( "\n" ); 9843d3b0591SJens Wiklander 9853d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */ 9863d3b0591SJens Wiklander 9873d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB) 9883d3b0591SJens Wiklander for( i = 0; i < 3; i++ ) 9893d3b0591SJens Wiklander { 9903d3b0591SJens Wiklander /* Test CFB encryption */ 9913d3b0591SJens Wiklander if( verbose ) 9923d3b0591SJens Wiklander mbedtls_printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i ); 9933d3b0591SJens Wiklander mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); 9943d3b0591SJens Wiklander memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); 9953d3b0591SJens Wiklander memset( buf, 0x55, sizeof( buf ) ); 9963d3b0591SJens Wiklander j = 0; 9973d3b0591SJens Wiklander mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, 9983d3b0591SJens Wiklander aria_test2_pt, buf ); 9993d3b0591SJens Wiklander if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ) 10003d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 10013d3b0591SJens Wiklander 10023d3b0591SJens Wiklander /* Test CFB decryption */ 10033d3b0591SJens Wiklander if( verbose ) 10043d3b0591SJens Wiklander mbedtls_printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i ); 10053d3b0591SJens Wiklander mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); 10063d3b0591SJens Wiklander memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); 10073d3b0591SJens Wiklander memset( buf, 0xAA, sizeof( buf ) ); 10083d3b0591SJens Wiklander j = 0; 10093d3b0591SJens Wiklander mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, 10103d3b0591SJens Wiklander iv, aria_test2_cfb_ct[i], buf ); 10113d3b0591SJens Wiklander if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) 10123d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 10133d3b0591SJens Wiklander } 10143d3b0591SJens Wiklander if( verbose ) 10153d3b0591SJens Wiklander mbedtls_printf( "\n" ); 10163d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */ 10173d3b0591SJens Wiklander 10183d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR) 10193d3b0591SJens Wiklander for( i = 0; i < 3; i++ ) 10203d3b0591SJens Wiklander { 10213d3b0591SJens Wiklander /* Test CTR encryption */ 10223d3b0591SJens Wiklander if( verbose ) 10233d3b0591SJens Wiklander mbedtls_printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i ); 10243d3b0591SJens Wiklander mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); 10253d3b0591SJens Wiklander memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 10263d3b0591SJens Wiklander memset( buf, 0x55, sizeof( buf ) ); 10273d3b0591SJens Wiklander j = 0; 10283d3b0591SJens Wiklander mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, 10293d3b0591SJens Wiklander aria_test2_pt, buf ); 10303d3b0591SJens Wiklander if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ) 10313d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 10323d3b0591SJens Wiklander 10333d3b0591SJens Wiklander /* Test CTR decryption */ 10343d3b0591SJens Wiklander if( verbose ) 10353d3b0591SJens Wiklander mbedtls_printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i ); 10363d3b0591SJens Wiklander mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); 10373d3b0591SJens Wiklander memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 10383d3b0591SJens Wiklander memset( buf, 0xAA, sizeof( buf ) ); 10393d3b0591SJens Wiklander j = 0; 10403d3b0591SJens Wiklander mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, 10413d3b0591SJens Wiklander aria_test2_ctr_ct[i], buf ); 10423d3b0591SJens Wiklander if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) 10433d3b0591SJens Wiklander ARIA_SELF_TEST_IF_FAIL; 10443d3b0591SJens Wiklander } 10453d3b0591SJens Wiklander if( verbose ) 10463d3b0591SJens Wiklander mbedtls_printf( "\n" ); 10473d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */ 10483d3b0591SJens Wiklander 10497901324dSJerome Forissier ret = 0; 10507901324dSJerome Forissier 10517901324dSJerome Forissier exit: 10527901324dSJerome Forissier mbedtls_aria_free( &ctx ); 10537901324dSJerome Forissier return( ret ); 10543d3b0591SJens Wiklander } 10553d3b0591SJens Wiklander 10563d3b0591SJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 10573d3b0591SJens Wiklander 10583d3b0591SJens Wiklander #endif /* MBEDTLS_ARIA_C */ 1059