xref: /optee_os/lib/libmbedtls/mbedtls/library/aria.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
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 #include "mbedtls/platform.h"
353d3b0591SJens Wiklander 
363d3b0591SJens Wiklander #if !defined(MBEDTLS_ARIA_ALT)
373d3b0591SJens Wiklander 
383d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
393d3b0591SJens Wiklander 
403d3b0591SJens Wiklander /* Parameter validation macros */
413d3b0591SJens Wiklander #define ARIA_VALIDATE_RET(cond)                                       \
423d3b0591SJens Wiklander     MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA)
433d3b0591SJens Wiklander #define ARIA_VALIDATE(cond)                                           \
443d3b0591SJens Wiklander     MBEDTLS_INTERNAL_VALIDATE(cond)
453d3b0591SJens Wiklander 
463d3b0591SJens Wiklander /*
473d3b0591SJens Wiklander  * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
483d3b0591SJens Wiklander  *
493d3b0591SJens Wiklander  * This is submatrix P1 in [1] Appendix B.1
503d3b0591SJens Wiklander  *
513d3b0591SJens Wiklander  * Common compilers fail to translate this to minimal number of instructions,
523d3b0591SJens Wiklander  * so let's provide asm versions for common platforms with C fallback.
533d3b0591SJens Wiklander  */
543d3b0591SJens Wiklander #if defined(MBEDTLS_HAVE_ASM)
553d3b0591SJens Wiklander #if defined(__arm__) /* rev16 available from v6 up */
563d3b0591SJens Wiklander /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
573d3b0591SJens Wiklander #if defined(__GNUC__) && \
583d3b0591SJens Wiklander     (!defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000) && \
593d3b0591SJens Wiklander     __ARM_ARCH >= 6
603d3b0591SJens Wiklander static inline uint32_t aria_p1(uint32_t x)
613d3b0591SJens Wiklander {
623d3b0591SJens Wiklander     uint32_t r;
633d3b0591SJens Wiklander     __asm("rev16 %0, %1" : "=l" (r) : "l" (x));
64*32b31808SJens Wiklander     return r;
653d3b0591SJens Wiklander }
663d3b0591SJens Wiklander #define ARIA_P1 aria_p1
673d3b0591SJens Wiklander #elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
683d3b0591SJens Wiklander     (__TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3)
693d3b0591SJens Wiklander static inline uint32_t aria_p1(uint32_t x)
703d3b0591SJens Wiklander {
713d3b0591SJens Wiklander     uint32_t r;
723d3b0591SJens Wiklander     __asm("rev16 r, x");
73*32b31808SJens Wiklander     return r;
743d3b0591SJens Wiklander }
753d3b0591SJens Wiklander #define ARIA_P1 aria_p1
763d3b0591SJens Wiklander #endif
773d3b0591SJens Wiklander #endif /* arm */
783d3b0591SJens Wiklander #if defined(__GNUC__) && \
793d3b0591SJens Wiklander     defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
803d3b0591SJens Wiklander /* I couldn't find an Intel equivalent of rev16, so two instructions */
813d3b0591SJens Wiklander #define ARIA_P1(x) ARIA_P2(ARIA_P3(x))
823d3b0591SJens Wiklander #endif /* x86 gnuc */
833d3b0591SJens Wiklander #endif /* MBEDTLS_HAVE_ASM && GNUC */
843d3b0591SJens Wiklander #if !defined(ARIA_P1)
853d3b0591SJens Wiklander #define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
863d3b0591SJens Wiklander #endif
873d3b0591SJens Wiklander 
883d3b0591SJens Wiklander /*
893d3b0591SJens Wiklander  * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
903d3b0591SJens Wiklander  *
913d3b0591SJens Wiklander  * This is submatrix P2 in [1] Appendix B.1
923d3b0591SJens Wiklander  *
933d3b0591SJens Wiklander  * Common compilers will translate this to a single instruction.
943d3b0591SJens Wiklander  */
953d3b0591SJens Wiklander #define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
963d3b0591SJens Wiklander 
973d3b0591SJens Wiklander /*
983d3b0591SJens Wiklander  * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
993d3b0591SJens Wiklander  *
1003d3b0591SJens Wiklander  * This is submatrix P3 in [1] Appendix B.1
1013d3b0591SJens Wiklander  */
102*32b31808SJens Wiklander #define ARIA_P3(x) MBEDTLS_BSWAP32(x)
1033d3b0591SJens Wiklander 
1043d3b0591SJens Wiklander /*
1053d3b0591SJens Wiklander  * ARIA Affine Transform
1063d3b0591SJens Wiklander  * (a, b, c, d) = state in/out
1073d3b0591SJens Wiklander  *
1083d3b0591SJens Wiklander  * If we denote the first byte of input by 0, ..., the last byte by f,
1093d3b0591SJens Wiklander  * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
1103d3b0591SJens Wiklander  *
1113d3b0591SJens Wiklander  * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple
1123d3b0591SJens Wiklander  * rearrangements on adjacent pairs, output is:
1133d3b0591SJens Wiklander  *
1143d3b0591SJens Wiklander  * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
1153d3b0591SJens Wiklander  *   = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
1163d3b0591SJens Wiklander  * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd
1173d3b0591SJens Wiklander  *   = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
1183d3b0591SJens Wiklander  * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe
1193d3b0591SJens Wiklander  *   = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
1203d3b0591SJens Wiklander  * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef
1213d3b0591SJens Wiklander  *   = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
1223d3b0591SJens Wiklander  *
1233d3b0591SJens Wiklander  * Note: another presentation of the A transform can be found as the first
1243d3b0591SJens Wiklander  * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
1253d3b0591SJens Wiklander  * The implementation below uses only P1 and P2 as they are sufficient.
1263d3b0591SJens Wiklander  */
1273d3b0591SJens Wiklander static inline void aria_a(uint32_t *a, uint32_t *b,
1283d3b0591SJens Wiklander                           uint32_t *c, uint32_t *d)
1293d3b0591SJens Wiklander {
1303d3b0591SJens Wiklander     uint32_t ta, tb, tc;
1313d3b0591SJens Wiklander     ta  =  *b;                      // 4567
1323d3b0591SJens Wiklander     *b  =  *a;                      // 0123
1333d3b0591SJens Wiklander     *a  =  ARIA_P2(ta);             // 6745
1343d3b0591SJens Wiklander     tb  =  ARIA_P2(*d);             // efcd
1353d3b0591SJens Wiklander     *d  =  ARIA_P1(*c);             // 98ba
1363d3b0591SJens Wiklander     *c  =  ARIA_P1(tb);             // fedc
1373d3b0591SJens Wiklander     ta  ^= *d;                      // 4567+98ba
1383d3b0591SJens Wiklander     tc  =  ARIA_P2(*b);             // 2301
1393d3b0591SJens Wiklander     ta  =  ARIA_P1(ta) ^ tc ^ *c;   // 2301+5476+89ab+fedc
1403d3b0591SJens Wiklander     tb  ^= ARIA_P2(*d);             // ba98+efcd
1413d3b0591SJens Wiklander     tc  ^= ARIA_P1(*a);             // 2301+7654
1423d3b0591SJens Wiklander     *b  ^= ta ^ tb;                 // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
1433d3b0591SJens Wiklander     tb  =  ARIA_P2(tb) ^ ta;        // 2301+5476+89ab+98ba+cdef+fedc
1443d3b0591SJens Wiklander     *a  ^= ARIA_P1(tb);             // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
1453d3b0591SJens Wiklander     ta  =  ARIA_P2(ta);             // 0123+7654+ab89+dcfe
1463d3b0591SJens Wiklander     *d  ^= ARIA_P1(ta) ^ tc;        // 1032+2301+6745+7654+98ba+ba98+cdef OUT
1473d3b0591SJens Wiklander     tc  =  ARIA_P2(tc);             // 0123+5476
1483d3b0591SJens Wiklander     *c  ^= ARIA_P1(tc) ^ ta;        // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
1493d3b0591SJens Wiklander }
1503d3b0591SJens Wiklander 
1513d3b0591SJens Wiklander /*
1523d3b0591SJens Wiklander  * ARIA Substitution Layer SL1 / SL2
1533d3b0591SJens Wiklander  * (a, b, c, d) = state in/out
1543d3b0591SJens Wiklander  * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
1553d3b0591SJens Wiklander  *
1563d3b0591SJens Wiklander  * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
1573d3b0591SJens Wiklander  * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
1583d3b0591SJens Wiklander  */
1593d3b0591SJens Wiklander static inline void aria_sl(uint32_t *a, uint32_t *b,
1603d3b0591SJens Wiklander                            uint32_t *c, uint32_t *d,
1613d3b0591SJens Wiklander                            const uint8_t sa[256], const uint8_t sb[256],
1623d3b0591SJens Wiklander                            const uint8_t sc[256], const uint8_t sd[256])
1633d3b0591SJens Wiklander {
164039e02dfSJerome Forissier     *a = ((uint32_t) sa[MBEDTLS_BYTE_0(*a)]) ^
165039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*a)]) <<  8) ^
166039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*a)]) << 16) ^
167039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*a)]) << 24);
168039e02dfSJerome Forissier     *b = ((uint32_t) sa[MBEDTLS_BYTE_0(*b)]) ^
169039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*b)]) <<  8) ^
170039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*b)]) << 16) ^
171039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*b)]) << 24);
172039e02dfSJerome Forissier     *c = ((uint32_t) sa[MBEDTLS_BYTE_0(*c)]) ^
173039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*c)]) <<  8) ^
174039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*c)]) << 16) ^
175039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*c)]) << 24);
176039e02dfSJerome Forissier     *d = ((uint32_t) sa[MBEDTLS_BYTE_0(*d)]) ^
177039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*d)]) <<  8) ^
178039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*d)]) << 16) ^
179039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*d)]) << 24);
1803d3b0591SJens Wiklander }
1813d3b0591SJens Wiklander 
1823d3b0591SJens Wiklander /*
1833d3b0591SJens Wiklander  * S-Boxes
1843d3b0591SJens Wiklander  */
1853d3b0591SJens Wiklander static const uint8_t aria_sb1[256] =
1863d3b0591SJens Wiklander {
1873d3b0591SJens Wiklander     0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
1883d3b0591SJens Wiklander     0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
1893d3b0591SJens Wiklander     0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
1903d3b0591SJens Wiklander     0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
1913d3b0591SJens Wiklander     0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
1923d3b0591SJens Wiklander     0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
1933d3b0591SJens Wiklander     0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
1943d3b0591SJens Wiklander     0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
1953d3b0591SJens Wiklander     0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
1963d3b0591SJens Wiklander     0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
1973d3b0591SJens Wiklander     0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
1983d3b0591SJens Wiklander     0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
1993d3b0591SJens Wiklander     0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
2003d3b0591SJens Wiklander     0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
2013d3b0591SJens Wiklander     0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
2023d3b0591SJens Wiklander     0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
2033d3b0591SJens Wiklander     0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
2043d3b0591SJens Wiklander     0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
2053d3b0591SJens Wiklander     0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
2063d3b0591SJens Wiklander     0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
2073d3b0591SJens Wiklander     0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
2083d3b0591SJens Wiklander     0xB0, 0x54, 0xBB, 0x16
2093d3b0591SJens Wiklander };
2103d3b0591SJens Wiklander 
2113d3b0591SJens Wiklander static const uint8_t aria_sb2[256] =
2123d3b0591SJens Wiklander {
2133d3b0591SJens Wiklander     0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
2143d3b0591SJens Wiklander     0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
2153d3b0591SJens Wiklander     0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
2163d3b0591SJens Wiklander     0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
2173d3b0591SJens Wiklander     0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
2183d3b0591SJens Wiklander     0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
2193d3b0591SJens Wiklander     0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
2203d3b0591SJens Wiklander     0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
2213d3b0591SJens Wiklander     0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
2223d3b0591SJens Wiklander     0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
2233d3b0591SJens Wiklander     0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
2243d3b0591SJens Wiklander     0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
2253d3b0591SJens Wiklander     0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
2263d3b0591SJens Wiklander     0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
2273d3b0591SJens Wiklander     0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
2283d3b0591SJens Wiklander     0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
2293d3b0591SJens Wiklander     0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
2303d3b0591SJens Wiklander     0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
2313d3b0591SJens Wiklander     0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
2323d3b0591SJens Wiklander     0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
2333d3b0591SJens Wiklander     0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
2343d3b0591SJens Wiklander     0xAF, 0xBA, 0xB5, 0x81
2353d3b0591SJens Wiklander };
2363d3b0591SJens Wiklander 
2373d3b0591SJens Wiklander static const uint8_t aria_is1[256] =
2383d3b0591SJens Wiklander {
2393d3b0591SJens Wiklander     0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
2403d3b0591SJens Wiklander     0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
2413d3b0591SJens Wiklander     0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
2423d3b0591SJens Wiklander     0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
2433d3b0591SJens Wiklander     0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
2443d3b0591SJens Wiklander     0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
2453d3b0591SJens Wiklander     0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
2463d3b0591SJens Wiklander     0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
2473d3b0591SJens Wiklander     0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
2483d3b0591SJens Wiklander     0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
2493d3b0591SJens Wiklander     0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
2503d3b0591SJens Wiklander     0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
2513d3b0591SJens Wiklander     0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
2523d3b0591SJens Wiklander     0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
2533d3b0591SJens Wiklander     0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
2543d3b0591SJens Wiklander     0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
2553d3b0591SJens Wiklander     0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
2563d3b0591SJens Wiklander     0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
2573d3b0591SJens Wiklander     0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
2583d3b0591SJens Wiklander     0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
2593d3b0591SJens Wiklander     0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
2603d3b0591SJens Wiklander     0x55, 0x21, 0x0C, 0x7D
2613d3b0591SJens Wiklander };
2623d3b0591SJens Wiklander 
2633d3b0591SJens Wiklander static const uint8_t aria_is2[256] =
2643d3b0591SJens Wiklander {
2653d3b0591SJens Wiklander     0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
2663d3b0591SJens Wiklander     0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
2673d3b0591SJens Wiklander     0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
2683d3b0591SJens Wiklander     0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
2693d3b0591SJens Wiklander     0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
2703d3b0591SJens Wiklander     0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
2713d3b0591SJens Wiklander     0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
2723d3b0591SJens Wiklander     0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
2733d3b0591SJens Wiklander     0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
2743d3b0591SJens Wiklander     0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
2753d3b0591SJens Wiklander     0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
2763d3b0591SJens Wiklander     0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
2773d3b0591SJens Wiklander     0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
2783d3b0591SJens Wiklander     0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
2793d3b0591SJens Wiklander     0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
2803d3b0591SJens Wiklander     0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
2813d3b0591SJens Wiklander     0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
2823d3b0591SJens Wiklander     0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
2833d3b0591SJens Wiklander     0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
2843d3b0591SJens Wiklander     0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
2853d3b0591SJens Wiklander     0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
2863d3b0591SJens Wiklander     0x03, 0xA2, 0xAC, 0x60
2873d3b0591SJens Wiklander };
2883d3b0591SJens Wiklander 
2893d3b0591SJens Wiklander /*
2903d3b0591SJens Wiklander  * Helper for key schedule: r = FO( p, k ) ^ x
2913d3b0591SJens Wiklander  */
2923d3b0591SJens Wiklander static void aria_fo_xor(uint32_t r[4], const uint32_t p[4],
2933d3b0591SJens Wiklander                         const uint32_t k[4], const uint32_t x[4])
2943d3b0591SJens Wiklander {
2953d3b0591SJens Wiklander     uint32_t a, b, c, d;
2963d3b0591SJens Wiklander 
2973d3b0591SJens Wiklander     a = p[0] ^ k[0];
2983d3b0591SJens Wiklander     b = p[1] ^ k[1];
2993d3b0591SJens Wiklander     c = p[2] ^ k[2];
3003d3b0591SJens Wiklander     d = p[3] ^ k[3];
3013d3b0591SJens Wiklander 
3023d3b0591SJens Wiklander     aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2);
3033d3b0591SJens Wiklander     aria_a(&a, &b, &c, &d);
3043d3b0591SJens Wiklander 
3053d3b0591SJens Wiklander     r[0] = a ^ x[0];
3063d3b0591SJens Wiklander     r[1] = b ^ x[1];
3073d3b0591SJens Wiklander     r[2] = c ^ x[2];
3083d3b0591SJens Wiklander     r[3] = d ^ x[3];
3093d3b0591SJens Wiklander }
3103d3b0591SJens Wiklander 
3113d3b0591SJens Wiklander /*
3123d3b0591SJens Wiklander  * Helper for key schedule: r = FE( p, k ) ^ x
3133d3b0591SJens Wiklander  */
3143d3b0591SJens Wiklander static void aria_fe_xor(uint32_t r[4], const uint32_t p[4],
3153d3b0591SJens Wiklander                         const uint32_t k[4], const uint32_t x[4])
3163d3b0591SJens Wiklander {
3173d3b0591SJens Wiklander     uint32_t a, b, c, d;
3183d3b0591SJens Wiklander 
3193d3b0591SJens Wiklander     a = p[0] ^ k[0];
3203d3b0591SJens Wiklander     b = p[1] ^ k[1];
3213d3b0591SJens Wiklander     c = p[2] ^ k[2];
3223d3b0591SJens Wiklander     d = p[3] ^ k[3];
3233d3b0591SJens Wiklander 
3243d3b0591SJens Wiklander     aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2);
3253d3b0591SJens Wiklander     aria_a(&a, &b, &c, &d);
3263d3b0591SJens Wiklander 
3273d3b0591SJens Wiklander     r[0] = a ^ x[0];
3283d3b0591SJens Wiklander     r[1] = b ^ x[1];
3293d3b0591SJens Wiklander     r[2] = c ^ x[2];
3303d3b0591SJens Wiklander     r[3] = d ^ x[3];
3313d3b0591SJens Wiklander }
3323d3b0591SJens Wiklander 
3333d3b0591SJens Wiklander /*
3343d3b0591SJens Wiklander  * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
3353d3b0591SJens Wiklander  *
3363d3b0591SJens Wiklander  * We chose to store bytes into 32-bit words in little-endian format (see
337039e02dfSJerome Forissier  * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse
338039e02dfSJerome Forissier  * bytes here.
3393d3b0591SJens Wiklander  */
3403d3b0591SJens Wiklander static void aria_rot128(uint32_t r[4], const uint32_t a[4],
3413d3b0591SJens Wiklander                         const uint32_t b[4], uint8_t n)
3423d3b0591SJens Wiklander {
3433d3b0591SJens Wiklander     uint8_t i, j;
3443d3b0591SJens Wiklander     uint32_t t, u;
3453d3b0591SJens Wiklander 
3463d3b0591SJens Wiklander     const uint8_t n1 = n % 32;              // bit offset
3473d3b0591SJens Wiklander     const uint8_t n2 = n1 ? 32 - n1 : 0;    // reverse bit offset
3483d3b0591SJens Wiklander 
3493d3b0591SJens Wiklander     j = (n / 32) % 4;                       // initial word offset
3503d3b0591SJens Wiklander     t = ARIA_P3(b[j]);                      // big endian
351*32b31808SJens Wiklander     for (i = 0; i < 4; i++) {
3523d3b0591SJens Wiklander         j = (j + 1) % 4;                    // get next word, big endian
3533d3b0591SJens Wiklander         u = ARIA_P3(b[j]);
3543d3b0591SJens Wiklander         t <<= n1;                           // rotate
3553d3b0591SJens Wiklander         t |= u >> n2;
3563d3b0591SJens Wiklander         t = ARIA_P3(t);                     // back to little endian
3573d3b0591SJens Wiklander         r[i] = a[i] ^ t;                    // store
3583d3b0591SJens Wiklander         t = u;                              // move to next word
3593d3b0591SJens Wiklander     }
3603d3b0591SJens Wiklander }
3613d3b0591SJens Wiklander 
3623d3b0591SJens Wiklander /*
3633d3b0591SJens Wiklander  * Set encryption key
3643d3b0591SJens Wiklander  */
3653d3b0591SJens Wiklander int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
3663d3b0591SJens Wiklander                             const unsigned char *key, unsigned int keybits)
3673d3b0591SJens Wiklander {
3683d3b0591SJens Wiklander     /* round constant masks */
3693d3b0591SJens Wiklander     const uint32_t rc[3][4] =
3703d3b0591SJens Wiklander     {
3713d3b0591SJens Wiklander         {   0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA  },
3723d3b0591SJens Wiklander         {   0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF  },
3733d3b0591SJens Wiklander         {   0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804  }
3743d3b0591SJens Wiklander     };
3753d3b0591SJens Wiklander 
3763d3b0591SJens Wiklander     int i;
3773d3b0591SJens Wiklander     uint32_t w[4][4], *w2;
3783d3b0591SJens Wiklander     ARIA_VALIDATE_RET(ctx != NULL);
3793d3b0591SJens Wiklander     ARIA_VALIDATE_RET(key != NULL);
3803d3b0591SJens Wiklander 
381*32b31808SJens Wiklander     if (keybits != 128 && keybits != 192 && keybits != 256) {
382*32b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
383*32b31808SJens Wiklander     }
3843d3b0591SJens Wiklander 
3853d3b0591SJens Wiklander     /* Copy key to W0 (and potential remainder to W1) */
386039e02dfSJerome Forissier     w[0][0] = MBEDTLS_GET_UINT32_LE(key,  0);
387039e02dfSJerome Forissier     w[0][1] = MBEDTLS_GET_UINT32_LE(key,  4);
388039e02dfSJerome Forissier     w[0][2] = MBEDTLS_GET_UINT32_LE(key,  8);
389039e02dfSJerome Forissier     w[0][3] = MBEDTLS_GET_UINT32_LE(key, 12);
3903d3b0591SJens Wiklander 
3913d3b0591SJens Wiklander     memset(w[1], 0, 16);
392*32b31808SJens Wiklander     if (keybits >= 192) {
393039e02dfSJerome Forissier         w[1][0] = MBEDTLS_GET_UINT32_LE(key, 16);    // 192 bit key
394039e02dfSJerome Forissier         w[1][1] = MBEDTLS_GET_UINT32_LE(key, 20);
3953d3b0591SJens Wiklander     }
396*32b31808SJens Wiklander     if (keybits == 256) {
397039e02dfSJerome Forissier         w[1][2] = MBEDTLS_GET_UINT32_LE(key, 24);    // 256 bit key
398039e02dfSJerome Forissier         w[1][3] = MBEDTLS_GET_UINT32_LE(key, 28);
3993d3b0591SJens Wiklander     }
4003d3b0591SJens Wiklander 
4013d3b0591SJens Wiklander     i = (keybits - 128) >> 6;               // index: 0, 1, 2
4023d3b0591SJens Wiklander     ctx->nr = 12 + 2 * i;                   // no. rounds: 12, 14, 16
4033d3b0591SJens Wiklander 
4043d3b0591SJens Wiklander     aria_fo_xor(w[1], w[0], rc[i], w[1]);   // W1 = FO(W0, CK1) ^ KR
4053d3b0591SJens Wiklander     i = i < 2 ? i + 1 : 0;
4063d3b0591SJens Wiklander     aria_fe_xor(w[2], w[1], rc[i], w[0]);   // W2 = FE(W1, CK2) ^ W0
4073d3b0591SJens Wiklander     i = i < 2 ? i + 1 : 0;
4083d3b0591SJens Wiklander     aria_fo_xor(w[3], w[2], rc[i], w[1]);   // W3 = FO(W2, CK3) ^ W1
4093d3b0591SJens Wiklander 
410*32b31808SJens Wiklander     for (i = 0; i < 4; i++) {               // create round keys
4113d3b0591SJens Wiklander         w2 = w[(i + 1) & 3];
4123d3b0591SJens Wiklander         aria_rot128(ctx->rk[i], w[i], w2, 128 - 19);
4133d3b0591SJens Wiklander         aria_rot128(ctx->rk[i +  4], w[i], w2, 128 - 31);
4143d3b0591SJens Wiklander         aria_rot128(ctx->rk[i +  8], w[i], w2,       61);
4153d3b0591SJens Wiklander         aria_rot128(ctx->rk[i + 12], w[i], w2,       31);
4163d3b0591SJens Wiklander     }
4173d3b0591SJens Wiklander     aria_rot128(ctx->rk[16], w[0], w[1], 19);
4183d3b0591SJens Wiklander 
4193d3b0591SJens Wiklander     /* w holds enough info to reconstruct the round keys */
4203d3b0591SJens Wiklander     mbedtls_platform_zeroize(w, sizeof(w));
4213d3b0591SJens Wiklander 
422*32b31808SJens Wiklander     return 0;
4233d3b0591SJens Wiklander }
4243d3b0591SJens Wiklander 
4253d3b0591SJens Wiklander /*
4263d3b0591SJens Wiklander  * Set decryption key
4273d3b0591SJens Wiklander  */
4283d3b0591SJens Wiklander int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
4293d3b0591SJens Wiklander                             const unsigned char *key, unsigned int keybits)
4303d3b0591SJens Wiklander {
4313d3b0591SJens Wiklander     int i, j, k, ret;
4323d3b0591SJens Wiklander     ARIA_VALIDATE_RET(ctx != NULL);
4333d3b0591SJens Wiklander     ARIA_VALIDATE_RET(key != NULL);
4343d3b0591SJens Wiklander 
4353d3b0591SJens Wiklander     ret = mbedtls_aria_setkey_enc(ctx, key, keybits);
436*32b31808SJens Wiklander     if (ret != 0) {
437*32b31808SJens Wiklander         return ret;
438*32b31808SJens Wiklander     }
4393d3b0591SJens Wiklander 
4403d3b0591SJens Wiklander     /* flip the order of round keys */
441*32b31808SJens Wiklander     for (i = 0, j = ctx->nr; i < j; i++, j--) {
442*32b31808SJens Wiklander         for (k = 0; k < 4; k++) {
4433d3b0591SJens Wiklander             uint32_t t = ctx->rk[i][k];
4443d3b0591SJens Wiklander             ctx->rk[i][k] = ctx->rk[j][k];
4453d3b0591SJens Wiklander             ctx->rk[j][k] = t;
4463d3b0591SJens Wiklander         }
4473d3b0591SJens Wiklander     }
4483d3b0591SJens Wiklander 
4493d3b0591SJens Wiklander     /* apply affine transform to middle keys */
450*32b31808SJens Wiklander     for (i = 1; i < ctx->nr; i++) {
4513d3b0591SJens Wiklander         aria_a(&ctx->rk[i][0], &ctx->rk[i][1],
4523d3b0591SJens Wiklander                &ctx->rk[i][2], &ctx->rk[i][3]);
4533d3b0591SJens Wiklander     }
4543d3b0591SJens Wiklander 
455*32b31808SJens Wiklander     return 0;
4563d3b0591SJens Wiklander }
4573d3b0591SJens Wiklander 
4583d3b0591SJens Wiklander /*
4593d3b0591SJens Wiklander  * Encrypt a block
4603d3b0591SJens Wiklander  */
4613d3b0591SJens Wiklander int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
4623d3b0591SJens Wiklander                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
4633d3b0591SJens Wiklander                            unsigned char output[MBEDTLS_ARIA_BLOCKSIZE])
4643d3b0591SJens Wiklander {
4653d3b0591SJens Wiklander     int i;
4663d3b0591SJens Wiklander 
4673d3b0591SJens Wiklander     uint32_t a, b, c, d;
4683d3b0591SJens Wiklander     ARIA_VALIDATE_RET(ctx != NULL);
4693d3b0591SJens Wiklander     ARIA_VALIDATE_RET(input != NULL);
4703d3b0591SJens Wiklander     ARIA_VALIDATE_RET(output != NULL);
4713d3b0591SJens Wiklander 
472039e02dfSJerome Forissier     a = MBEDTLS_GET_UINT32_LE(input,  0);
473039e02dfSJerome Forissier     b = MBEDTLS_GET_UINT32_LE(input,  4);
474039e02dfSJerome Forissier     c = MBEDTLS_GET_UINT32_LE(input,  8);
475039e02dfSJerome Forissier     d = MBEDTLS_GET_UINT32_LE(input, 12);
4763d3b0591SJens Wiklander 
4773d3b0591SJens Wiklander     i = 0;
478*32b31808SJens Wiklander     while (1) {
4793d3b0591SJens Wiklander         a ^= ctx->rk[i][0];
4803d3b0591SJens Wiklander         b ^= ctx->rk[i][1];
4813d3b0591SJens Wiklander         c ^= ctx->rk[i][2];
4823d3b0591SJens Wiklander         d ^= ctx->rk[i][3];
4833d3b0591SJens Wiklander         i++;
4843d3b0591SJens Wiklander 
4853d3b0591SJens Wiklander         aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2);
4863d3b0591SJens Wiklander         aria_a(&a, &b, &c, &d);
4873d3b0591SJens Wiklander 
4883d3b0591SJens Wiklander         a ^= ctx->rk[i][0];
4893d3b0591SJens Wiklander         b ^= ctx->rk[i][1];
4903d3b0591SJens Wiklander         c ^= ctx->rk[i][2];
4913d3b0591SJens Wiklander         d ^= ctx->rk[i][3];
4923d3b0591SJens Wiklander         i++;
4933d3b0591SJens Wiklander 
4943d3b0591SJens Wiklander         aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2);
495*32b31808SJens Wiklander         if (i >= ctx->nr) {
4963d3b0591SJens Wiklander             break;
497*32b31808SJens Wiklander         }
4983d3b0591SJens Wiklander         aria_a(&a, &b, &c, &d);
4993d3b0591SJens Wiklander     }
5003d3b0591SJens Wiklander 
5013d3b0591SJens Wiklander     /* final key mixing */
5023d3b0591SJens Wiklander     a ^= ctx->rk[i][0];
5033d3b0591SJens Wiklander     b ^= ctx->rk[i][1];
5043d3b0591SJens Wiklander     c ^= ctx->rk[i][2];
5053d3b0591SJens Wiklander     d ^= ctx->rk[i][3];
5063d3b0591SJens Wiklander 
507039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(a, output,  0);
508039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(b, output,  4);
509039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(c, output,  8);
510039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(d, output, 12);
5113d3b0591SJens Wiklander 
512*32b31808SJens Wiklander     return 0;
5133d3b0591SJens Wiklander }
5143d3b0591SJens Wiklander 
5153d3b0591SJens Wiklander /* Initialize context */
5163d3b0591SJens Wiklander void mbedtls_aria_init(mbedtls_aria_context *ctx)
5173d3b0591SJens Wiklander {
5183d3b0591SJens Wiklander     ARIA_VALIDATE(ctx != NULL);
5193d3b0591SJens Wiklander     memset(ctx, 0, sizeof(mbedtls_aria_context));
5203d3b0591SJens Wiklander }
5213d3b0591SJens Wiklander 
5223d3b0591SJens Wiklander /* Clear context */
5233d3b0591SJens Wiklander void mbedtls_aria_free(mbedtls_aria_context *ctx)
5243d3b0591SJens Wiklander {
525*32b31808SJens Wiklander     if (ctx == NULL) {
5263d3b0591SJens Wiklander         return;
527*32b31808SJens Wiklander     }
5283d3b0591SJens Wiklander 
5293d3b0591SJens Wiklander     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aria_context));
5303d3b0591SJens Wiklander }
5313d3b0591SJens Wiklander 
5323d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
5333d3b0591SJens Wiklander /*
5343d3b0591SJens Wiklander  * ARIA-CBC buffer encryption/decryption
5353d3b0591SJens Wiklander  */
5363d3b0591SJens Wiklander int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
5373d3b0591SJens Wiklander                            int mode,
5383d3b0591SJens Wiklander                            size_t length,
5393d3b0591SJens Wiklander                            unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
5403d3b0591SJens Wiklander                            const unsigned char *input,
5413d3b0591SJens Wiklander                            unsigned char *output)
5423d3b0591SJens Wiklander {
5433d3b0591SJens Wiklander     unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
5443d3b0591SJens Wiklander 
5453d3b0591SJens Wiklander     ARIA_VALIDATE_RET(ctx != NULL);
5463d3b0591SJens Wiklander     ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
5473d3b0591SJens Wiklander                       mode == MBEDTLS_ARIA_DECRYPT);
5483d3b0591SJens Wiklander     ARIA_VALIDATE_RET(length == 0 || input  != NULL);
5493d3b0591SJens Wiklander     ARIA_VALIDATE_RET(length == 0 || output != NULL);
5503d3b0591SJens Wiklander     ARIA_VALIDATE_RET(iv != NULL);
5513d3b0591SJens Wiklander 
552*32b31808SJens Wiklander     if (length % MBEDTLS_ARIA_BLOCKSIZE) {
553*32b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH;
554*32b31808SJens Wiklander     }
5553d3b0591SJens Wiklander 
556*32b31808SJens Wiklander     if (mode == MBEDTLS_ARIA_DECRYPT) {
557*32b31808SJens Wiklander         while (length > 0) {
5583d3b0591SJens Wiklander             memcpy(temp, input, MBEDTLS_ARIA_BLOCKSIZE);
5593d3b0591SJens Wiklander             mbedtls_aria_crypt_ecb(ctx, input, output);
5603d3b0591SJens Wiklander 
561*32b31808SJens Wiklander             mbedtls_xor(output, output, iv, MBEDTLS_ARIA_BLOCKSIZE);
5623d3b0591SJens Wiklander 
5633d3b0591SJens Wiklander             memcpy(iv, temp, MBEDTLS_ARIA_BLOCKSIZE);
5643d3b0591SJens Wiklander 
5653d3b0591SJens Wiklander             input  += MBEDTLS_ARIA_BLOCKSIZE;
5663d3b0591SJens Wiklander             output += MBEDTLS_ARIA_BLOCKSIZE;
5673d3b0591SJens Wiklander             length -= MBEDTLS_ARIA_BLOCKSIZE;
5683d3b0591SJens Wiklander         }
569*32b31808SJens Wiklander     } else {
570*32b31808SJens Wiklander         while (length > 0) {
571*32b31808SJens Wiklander             mbedtls_xor(output, input, iv, MBEDTLS_ARIA_BLOCKSIZE);
5723d3b0591SJens Wiklander 
5733d3b0591SJens Wiklander             mbedtls_aria_crypt_ecb(ctx, output, output);
5743d3b0591SJens Wiklander             memcpy(iv, output, MBEDTLS_ARIA_BLOCKSIZE);
5753d3b0591SJens Wiklander 
5763d3b0591SJens Wiklander             input  += MBEDTLS_ARIA_BLOCKSIZE;
5773d3b0591SJens Wiklander             output += MBEDTLS_ARIA_BLOCKSIZE;
5783d3b0591SJens Wiklander             length -= MBEDTLS_ARIA_BLOCKSIZE;
5793d3b0591SJens Wiklander         }
5803d3b0591SJens Wiklander     }
5813d3b0591SJens Wiklander 
582*32b31808SJens Wiklander     return 0;
5833d3b0591SJens Wiklander }
5843d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
5853d3b0591SJens Wiklander 
5863d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
5873d3b0591SJens Wiklander /*
5883d3b0591SJens Wiklander  * ARIA-CFB128 buffer encryption/decryption
5893d3b0591SJens Wiklander  */
5903d3b0591SJens Wiklander int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
5913d3b0591SJens Wiklander                               int mode,
5923d3b0591SJens Wiklander                               size_t length,
5933d3b0591SJens Wiklander                               size_t *iv_off,
5943d3b0591SJens Wiklander                               unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
5953d3b0591SJens Wiklander                               const unsigned char *input,
5963d3b0591SJens Wiklander                               unsigned char *output)
5973d3b0591SJens Wiklander {
5983d3b0591SJens Wiklander     unsigned char c;
5993d3b0591SJens Wiklander     size_t n;
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     ARIA_VALIDATE_RET(iv_off != NULL);
6083d3b0591SJens Wiklander 
6093d3b0591SJens Wiklander     n = *iv_off;
6103d3b0591SJens Wiklander 
6113d3b0591SJens Wiklander     /* An overly large value of n can lead to an unlimited
6123d3b0591SJens Wiklander      * buffer overflow. Therefore, guard against this
6133d3b0591SJens Wiklander      * outside of parameter validation. */
614*32b31808SJens Wiklander     if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
615*32b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
616*32b31808SJens Wiklander     }
6173d3b0591SJens Wiklander 
618*32b31808SJens Wiklander     if (mode == MBEDTLS_ARIA_DECRYPT) {
619*32b31808SJens Wiklander         while (length--) {
620*32b31808SJens Wiklander             if (n == 0) {
6213d3b0591SJens Wiklander                 mbedtls_aria_crypt_ecb(ctx, iv, iv);
622*32b31808SJens Wiklander             }
6233d3b0591SJens Wiklander 
6243d3b0591SJens Wiklander             c = *input++;
6253d3b0591SJens Wiklander             *output++ = c ^ iv[n];
6263d3b0591SJens Wiklander             iv[n] = c;
6273d3b0591SJens Wiklander 
6283d3b0591SJens Wiklander             n = (n + 1) & 0x0F;
6293d3b0591SJens Wiklander         }
630*32b31808SJens Wiklander     } else {
631*32b31808SJens Wiklander         while (length--) {
632*32b31808SJens Wiklander             if (n == 0) {
6333d3b0591SJens Wiklander                 mbedtls_aria_crypt_ecb(ctx, iv, iv);
634*32b31808SJens Wiklander             }
6353d3b0591SJens Wiklander 
6363d3b0591SJens Wiklander             iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
6373d3b0591SJens Wiklander 
6383d3b0591SJens Wiklander             n = (n + 1) & 0x0F;
6393d3b0591SJens Wiklander         }
6403d3b0591SJens Wiklander     }
6413d3b0591SJens Wiklander 
6423d3b0591SJens Wiklander     *iv_off = n;
6433d3b0591SJens Wiklander 
644*32b31808SJens Wiklander     return 0;
6453d3b0591SJens Wiklander }
6463d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
6473d3b0591SJens Wiklander 
6483d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
6493d3b0591SJens Wiklander /*
6503d3b0591SJens Wiklander  * ARIA-CTR buffer encryption/decryption
6513d3b0591SJens Wiklander  */
6523d3b0591SJens Wiklander int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
6533d3b0591SJens Wiklander                            size_t length,
6543d3b0591SJens Wiklander                            size_t *nc_off,
6553d3b0591SJens Wiklander                            unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
6563d3b0591SJens Wiklander                            unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
6573d3b0591SJens Wiklander                            const unsigned char *input,
6583d3b0591SJens Wiklander                            unsigned char *output)
6593d3b0591SJens Wiklander {
6603d3b0591SJens Wiklander     int c, i;
6613d3b0591SJens Wiklander     size_t n;
6623d3b0591SJens Wiklander 
6633d3b0591SJens Wiklander     ARIA_VALIDATE_RET(ctx != NULL);
6643d3b0591SJens Wiklander     ARIA_VALIDATE_RET(length == 0 || input  != NULL);
6653d3b0591SJens Wiklander     ARIA_VALIDATE_RET(length == 0 || output != NULL);
6663d3b0591SJens Wiklander     ARIA_VALIDATE_RET(nonce_counter != NULL);
6673d3b0591SJens Wiklander     ARIA_VALIDATE_RET(stream_block  != NULL);
6683d3b0591SJens Wiklander     ARIA_VALIDATE_RET(nc_off != NULL);
6693d3b0591SJens Wiklander 
6703d3b0591SJens Wiklander     n = *nc_off;
6713d3b0591SJens Wiklander     /* An overly large value of n can lead to an unlimited
6723d3b0591SJens Wiklander      * buffer overflow. Therefore, guard against this
6733d3b0591SJens Wiklander      * outside of parameter validation. */
674*32b31808SJens Wiklander     if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
675*32b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
676*32b31808SJens Wiklander     }
6773d3b0591SJens Wiklander 
678*32b31808SJens Wiklander     while (length--) {
6793d3b0591SJens Wiklander         if (n == 0) {
6803d3b0591SJens Wiklander             mbedtls_aria_crypt_ecb(ctx, nonce_counter,
6813d3b0591SJens Wiklander                                    stream_block);
6823d3b0591SJens Wiklander 
683*32b31808SJens Wiklander             for (i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i--) {
684*32b31808SJens Wiklander                 if (++nonce_counter[i - 1] != 0) {
6853d3b0591SJens Wiklander                     break;
6863d3b0591SJens Wiklander                 }
687*32b31808SJens Wiklander             }
688*32b31808SJens Wiklander         }
6893d3b0591SJens Wiklander         c = *input++;
6903d3b0591SJens Wiklander         *output++ = (unsigned char) (c ^ stream_block[n]);
6913d3b0591SJens Wiklander 
6923d3b0591SJens Wiklander         n = (n + 1) & 0x0F;
6933d3b0591SJens Wiklander     }
6943d3b0591SJens Wiklander 
6953d3b0591SJens Wiklander     *nc_off = n;
6963d3b0591SJens Wiklander 
697*32b31808SJens Wiklander     return 0;
6983d3b0591SJens Wiklander }
6993d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
7003d3b0591SJens Wiklander #endif /* !MBEDTLS_ARIA_ALT */
7013d3b0591SJens Wiklander 
7023d3b0591SJens Wiklander #if defined(MBEDTLS_SELF_TEST)
7033d3b0591SJens Wiklander 
7043d3b0591SJens Wiklander /*
7053d3b0591SJens Wiklander  * Basic ARIA ECB test vectors from RFC 5794
7063d3b0591SJens Wiklander  */
7073d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_key[32] =           // test key
7083d3b0591SJens Wiklander {
7093d3b0591SJens Wiklander     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,     // 128 bit
7103d3b0591SJens Wiklander     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
7113d3b0591SJens Wiklander     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,     // 192 bit
7123d3b0591SJens Wiklander     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F      // 256 bit
7133d3b0591SJens Wiklander };
7143d3b0591SJens Wiklander 
7153d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] =            // plaintext
7163d3b0591SJens Wiklander {
7173d3b0591SJens Wiklander     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // same for all
7183d3b0591SJens Wiklander     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF      // key sizes
7193d3b0591SJens Wiklander };
7203d3b0591SJens Wiklander 
7213d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] =         // ciphertext
7223d3b0591SJens Wiklander {
7233d3b0591SJens Wiklander     { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73,   // 128 bit
7243d3b0591SJens Wiklander       0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
7253d3b0591SJens Wiklander     { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA,   // 192 bit
7263d3b0591SJens Wiklander       0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
7273d3b0591SJens Wiklander     { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F,   // 256 bit
7283d3b0591SJens Wiklander       0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
7293d3b0591SJens Wiklander };
7303d3b0591SJens Wiklander 
7313d3b0591SJens Wiklander /*
7323d3b0591SJens Wiklander  * Mode tests from "Test Vectors for ARIA"  Version 1.0
7333d3b0591SJens Wiklander  * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
7343d3b0591SJens Wiklander  */
7353d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
7363d3b0591SJens Wiklander     defined(MBEDTLS_CIPHER_MODE_CTR))
7373d3b0591SJens Wiklander static const uint8_t aria_test2_key[32] =
7383d3b0591SJens Wiklander {
7393d3b0591SJens Wiklander     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 128 bit
7403d3b0591SJens Wiklander     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
7413d3b0591SJens Wiklander     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 192 bit
7423d3b0591SJens Wiklander     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff      // 256 bit
7433d3b0591SJens Wiklander };
7443d3b0591SJens Wiklander 
7453d3b0591SJens Wiklander static const uint8_t aria_test2_pt[48] =
7463d3b0591SJens Wiklander {
7473d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa,     // same for all
7483d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
7493d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
7503d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
7513d3b0591SJens Wiklander     0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
7523d3b0591SJens Wiklander     0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
7533d3b0591SJens Wiklander };
7543d3b0591SJens Wiklander #endif
7553d3b0591SJens Wiklander 
7563d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
7573d3b0591SJens Wiklander static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] =
7583d3b0591SJens Wiklander {
7593d3b0591SJens Wiklander     0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,     // same for CBC, CFB
7603d3b0591SJens Wiklander     0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0      // CTR has zero IV
7613d3b0591SJens Wiklander };
7623d3b0591SJens Wiklander #endif
7633d3b0591SJens Wiklander 
7643d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
7653d3b0591SJens Wiklander static const uint8_t aria_test2_cbc_ct[3][48] =         // CBC ciphertext
7663d3b0591SJens Wiklander {
7673d3b0591SJens Wiklander     { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10,   // 128-bit key
7683d3b0591SJens Wiklander       0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
7693d3b0591SJens Wiklander       0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
7703d3b0591SJens Wiklander       0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
7713d3b0591SJens Wiklander       0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
7723d3b0591SJens Wiklander       0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
7733d3b0591SJens Wiklander     { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c,   // 192-bit key
7743d3b0591SJens Wiklander       0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
7753d3b0591SJens Wiklander       0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
7763d3b0591SJens Wiklander       0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
7773d3b0591SJens Wiklander       0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
7783d3b0591SJens Wiklander       0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
7793d3b0591SJens Wiklander     { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1,   // 256-bit key
7803d3b0591SJens Wiklander       0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
7813d3b0591SJens Wiklander       0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
7823d3b0591SJens Wiklander       0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
7833d3b0591SJens Wiklander       0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
7843d3b0591SJens Wiklander       0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
7853d3b0591SJens Wiklander };
7863d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
7873d3b0591SJens Wiklander 
7883d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
7893d3b0591SJens Wiklander static const uint8_t aria_test2_cfb_ct[3][48] =         // CFB ciphertext
7903d3b0591SJens Wiklander {
7913d3b0591SJens Wiklander     { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38,   // 128-bit key
7923d3b0591SJens Wiklander       0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
7933d3b0591SJens Wiklander       0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
7943d3b0591SJens Wiklander       0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
7953d3b0591SJens Wiklander       0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
7963d3b0591SJens Wiklander       0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
7973d3b0591SJens Wiklander     { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54,   // 192-bit key
7983d3b0591SJens Wiklander       0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
7993d3b0591SJens Wiklander       0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
8003d3b0591SJens Wiklander       0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
8013d3b0591SJens Wiklander       0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
8023d3b0591SJens Wiklander       0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
8033d3b0591SJens Wiklander     { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2,   // 256-bit key
8043d3b0591SJens Wiklander       0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
8053d3b0591SJens Wiklander       0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
8063d3b0591SJens Wiklander       0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
8073d3b0591SJens Wiklander       0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
8083d3b0591SJens Wiklander       0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
8093d3b0591SJens Wiklander };
8103d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
8113d3b0591SJens Wiklander 
8123d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
8133d3b0591SJens Wiklander static const uint8_t aria_test2_ctr_ct[3][48] =         // CTR ciphertext
8143d3b0591SJens Wiklander {
8153d3b0591SJens Wiklander     { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c,   // 128-bit key
8163d3b0591SJens Wiklander       0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
8173d3b0591SJens Wiklander       0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
8183d3b0591SJens Wiklander       0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
8193d3b0591SJens Wiklander       0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
8203d3b0591SJens Wiklander       0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
8213d3b0591SJens Wiklander     { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19,   // 192-bit key
8223d3b0591SJens Wiklander       0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
8233d3b0591SJens Wiklander       0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
8243d3b0591SJens Wiklander       0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
8253d3b0591SJens Wiklander       0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
8263d3b0591SJens Wiklander       0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
8273d3b0591SJens Wiklander     { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17,   // 256-bit key
8283d3b0591SJens Wiklander       0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
8293d3b0591SJens Wiklander       0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
8303d3b0591SJens Wiklander       0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
8313d3b0591SJens Wiklander       0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
8323d3b0591SJens Wiklander       0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
8333d3b0591SJens Wiklander };
8343d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
8353d3b0591SJens Wiklander 
836*32b31808SJens Wiklander #define ARIA_SELF_TEST_ASSERT(cond)                   \
837*32b31808SJens Wiklander     do {                                            \
838*32b31808SJens Wiklander         if (cond) {                                \
8393d3b0591SJens Wiklander             if (verbose)                           \
8403d3b0591SJens Wiklander             mbedtls_printf("failed\n");       \
8417901324dSJerome Forissier             goto exit;                              \
8423d3b0591SJens Wiklander         } else {                                    \
8433d3b0591SJens Wiklander             if (verbose)                           \
8443d3b0591SJens Wiklander             mbedtls_printf("passed\n");       \
845*32b31808SJens Wiklander         }                                           \
846*32b31808SJens Wiklander     } while (0)
8473d3b0591SJens Wiklander 
8483d3b0591SJens Wiklander /*
8493d3b0591SJens Wiklander  * Checkup routine
8503d3b0591SJens Wiklander  */
8513d3b0591SJens Wiklander int mbedtls_aria_self_test(int verbose)
8523d3b0591SJens Wiklander {
8533d3b0591SJens Wiklander     int i;
8543d3b0591SJens Wiklander     uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
8553d3b0591SJens Wiklander     mbedtls_aria_context ctx;
8567901324dSJerome Forissier     int ret = 1;
8573d3b0591SJens Wiklander 
8583d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
8593d3b0591SJens Wiklander     size_t j;
8603d3b0591SJens Wiklander #endif
8613d3b0591SJens Wiklander 
8623d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
8633d3b0591SJens Wiklander     defined(MBEDTLS_CIPHER_MODE_CFB) || \
8643d3b0591SJens Wiklander     defined(MBEDTLS_CIPHER_MODE_CTR))
8653d3b0591SJens Wiklander     uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
8663d3b0591SJens Wiklander #endif
8673d3b0591SJens Wiklander 
8687901324dSJerome Forissier     mbedtls_aria_init(&ctx);
8697901324dSJerome Forissier 
8703d3b0591SJens Wiklander     /*
8713d3b0591SJens Wiklander      * Test set 1
8723d3b0591SJens Wiklander      */
873*32b31808SJens Wiklander     for (i = 0; i < 3; i++) {
8743d3b0591SJens Wiklander         /* test ECB encryption */
875*32b31808SJens Wiklander         if (verbose) {
8763d3b0591SJens Wiklander             mbedtls_printf("  ARIA-ECB-%d (enc): ", 128 + 64 * i);
877*32b31808SJens Wiklander         }
8783d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test1_ecb_key, 128 + 64 * i);
8793d3b0591SJens Wiklander         mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_pt, blk);
880*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(
881*32b31808SJens Wiklander             memcmp(blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE)
882*32b31808SJens Wiklander             != 0);
8833d3b0591SJens Wiklander 
8843d3b0591SJens Wiklander         /* test ECB decryption */
885*32b31808SJens Wiklander         if (verbose) {
8863d3b0591SJens Wiklander             mbedtls_printf("  ARIA-ECB-%d (dec): ", 128 + 64 * i);
887*32b31808SJens Wiklander         }
8883d3b0591SJens Wiklander         mbedtls_aria_setkey_dec(&ctx, aria_test1_ecb_key, 128 + 64 * i);
8893d3b0591SJens Wiklander         mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_ct[i], blk);
890*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(
891*32b31808SJens Wiklander             memcmp(blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE)
892*32b31808SJens Wiklander             != 0);
8933d3b0591SJens Wiklander     }
894*32b31808SJens Wiklander     if (verbose) {
8953d3b0591SJens Wiklander         mbedtls_printf("\n");
896*32b31808SJens Wiklander     }
8973d3b0591SJens Wiklander 
8983d3b0591SJens Wiklander     /*
8993d3b0591SJens Wiklander      * Test set 2
9003d3b0591SJens Wiklander      */
9013d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
902*32b31808SJens Wiklander     for (i = 0; i < 3; i++) {
9033d3b0591SJens Wiklander         /* Test CBC encryption */
904*32b31808SJens Wiklander         if (verbose) {
9053d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CBC-%d (enc): ", 128 + 64 * i);
906*32b31808SJens Wiklander         }
9073d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9083d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
9093d3b0591SJens Wiklander         memset(buf, 0x55, sizeof(buf));
9103d3b0591SJens Wiklander         mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
9113d3b0591SJens Wiklander                                aria_test2_pt, buf);
912*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cbc_ct[i], 48)
913*32b31808SJens Wiklander                               != 0);
9143d3b0591SJens Wiklander 
9153d3b0591SJens Wiklander         /* Test CBC decryption */
916*32b31808SJens Wiklander         if (verbose) {
9173d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CBC-%d (dec): ", 128 + 64 * i);
918*32b31808SJens Wiklander         }
9193d3b0591SJens Wiklander         mbedtls_aria_setkey_dec(&ctx, aria_test2_key, 128 + 64 * i);
9203d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
9213d3b0591SJens Wiklander         memset(buf, 0xAA, sizeof(buf));
9223d3b0591SJens Wiklander         mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
9233d3b0591SJens Wiklander                                aria_test2_cbc_ct[i], buf);
924*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
9253d3b0591SJens Wiklander     }
926*32b31808SJens Wiklander     if (verbose) {
9273d3b0591SJens Wiklander         mbedtls_printf("\n");
928*32b31808SJens Wiklander     }
9293d3b0591SJens Wiklander 
9303d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
9313d3b0591SJens Wiklander 
9323d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
933*32b31808SJens Wiklander     for (i = 0; i < 3; i++) {
9343d3b0591SJens Wiklander         /* Test CFB encryption */
935*32b31808SJens Wiklander         if (verbose) {
9363d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CFB-%d (enc): ", 128 + 64 * i);
937*32b31808SJens Wiklander         }
9383d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9393d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
9403d3b0591SJens Wiklander         memset(buf, 0x55, sizeof(buf));
9413d3b0591SJens Wiklander         j = 0;
9423d3b0591SJens Wiklander         mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
9433d3b0591SJens Wiklander                                   aria_test2_pt, buf);
944*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cfb_ct[i], 48) != 0);
9453d3b0591SJens Wiklander 
9463d3b0591SJens Wiklander         /* Test CFB decryption */
947*32b31808SJens Wiklander         if (verbose) {
9483d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CFB-%d (dec): ", 128 + 64 * i);
949*32b31808SJens Wiklander         }
9503d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9513d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
9523d3b0591SJens Wiklander         memset(buf, 0xAA, sizeof(buf));
9533d3b0591SJens Wiklander         j = 0;
9543d3b0591SJens Wiklander         mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
9553d3b0591SJens Wiklander                                   iv, aria_test2_cfb_ct[i], buf);
956*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
9573d3b0591SJens Wiklander     }
958*32b31808SJens Wiklander     if (verbose) {
9593d3b0591SJens Wiklander         mbedtls_printf("\n");
960*32b31808SJens Wiklander     }
9613d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
9623d3b0591SJens Wiklander 
9633d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
964*32b31808SJens Wiklander     for (i = 0; i < 3; i++) {
9653d3b0591SJens Wiklander         /* Test CTR encryption */
966*32b31808SJens Wiklander         if (verbose) {
9673d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CTR-%d (enc): ", 128 + 64 * i);
968*32b31808SJens Wiklander         }
9693d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9703d3b0591SJens Wiklander         memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE);                      // IV = 0
9713d3b0591SJens Wiklander         memset(buf, 0x55, sizeof(buf));
9723d3b0591SJens Wiklander         j = 0;
9733d3b0591SJens Wiklander         mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk,
9743d3b0591SJens Wiklander                                aria_test2_pt, buf);
975*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_ctr_ct[i], 48) != 0);
9763d3b0591SJens Wiklander 
9773d3b0591SJens Wiklander         /* Test CTR decryption */
978*32b31808SJens Wiklander         if (verbose) {
9793d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CTR-%d (dec): ", 128 + 64 * i);
980*32b31808SJens Wiklander         }
9813d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9823d3b0591SJens Wiklander         memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE);                      // IV = 0
9833d3b0591SJens Wiklander         memset(buf, 0xAA, sizeof(buf));
9843d3b0591SJens Wiklander         j = 0;
9853d3b0591SJens Wiklander         mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk,
9863d3b0591SJens Wiklander                                aria_test2_ctr_ct[i], buf);
987*32b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
9883d3b0591SJens Wiklander     }
989*32b31808SJens Wiklander     if (verbose) {
9903d3b0591SJens Wiklander         mbedtls_printf("\n");
991*32b31808SJens Wiklander     }
9923d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
9933d3b0591SJens Wiklander 
9947901324dSJerome Forissier     ret = 0;
9957901324dSJerome Forissier 
9967901324dSJerome Forissier exit:
9977901324dSJerome Forissier     mbedtls_aria_free(&ctx);
998*32b31808SJens Wiklander     return ret;
9993d3b0591SJens Wiklander }
10003d3b0591SJens Wiklander 
10013d3b0591SJens Wiklander #endif /* MBEDTLS_SELF_TEST */
10023d3b0591SJens Wiklander 
10033d3b0591SJens Wiklander #endif /* MBEDTLS_ARIA_C */
1004