xref: /optee_os/lib/libmbedtls/mbedtls/library/aria.c (revision b0563631928755fe864b97785160fb3088e9efdc)
13d3b0591SJens Wiklander /*
23d3b0591SJens Wiklander  *  ARIA implementation
33d3b0591SJens Wiklander  *
47901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
5*b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
63d3b0591SJens Wiklander  */
73d3b0591SJens Wiklander 
83d3b0591SJens Wiklander /*
93d3b0591SJens Wiklander  * This implementation is based on the following standards:
103d3b0591SJens Wiklander  * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf
113d3b0591SJens Wiklander  * [2] https://tools.ietf.org/html/rfc5794
123d3b0591SJens Wiklander  */
133d3b0591SJens Wiklander 
147901324dSJerome Forissier #include "common.h"
153d3b0591SJens Wiklander 
163d3b0591SJens Wiklander #if defined(MBEDTLS_ARIA_C)
173d3b0591SJens Wiklander 
183d3b0591SJens Wiklander #include "mbedtls/aria.h"
193d3b0591SJens Wiklander 
203d3b0591SJens Wiklander #include <string.h>
213d3b0591SJens Wiklander 
223d3b0591SJens Wiklander #include "mbedtls/platform.h"
233d3b0591SJens Wiklander 
243d3b0591SJens Wiklander #if !defined(MBEDTLS_ARIA_ALT)
253d3b0591SJens Wiklander 
263d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
273d3b0591SJens Wiklander 
283d3b0591SJens Wiklander /*
293d3b0591SJens Wiklander  * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
303d3b0591SJens Wiklander  *
313d3b0591SJens Wiklander  * This is submatrix P1 in [1] Appendix B.1
323d3b0591SJens Wiklander  *
333d3b0591SJens Wiklander  * Common compilers fail to translate this to minimal number of instructions,
343d3b0591SJens Wiklander  * so let's provide asm versions for common platforms with C fallback.
353d3b0591SJens Wiklander  */
363d3b0591SJens Wiklander #if defined(MBEDTLS_HAVE_ASM)
373d3b0591SJens Wiklander #if defined(__arm__) /* rev16 available from v6 up */
383d3b0591SJens Wiklander /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
393d3b0591SJens Wiklander #if defined(__GNUC__) && \
403d3b0591SJens Wiklander     (!defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000) && \
413d3b0591SJens Wiklander     __ARM_ARCH >= 6
aria_p1(uint32_t x)423d3b0591SJens Wiklander static inline uint32_t aria_p1(uint32_t x)
433d3b0591SJens Wiklander {
443d3b0591SJens Wiklander     uint32_t r;
453d3b0591SJens Wiklander     __asm("rev16 %0, %1" : "=l" (r) : "l" (x));
4632b31808SJens Wiklander     return r;
473d3b0591SJens Wiklander }
483d3b0591SJens Wiklander #define ARIA_P1 aria_p1
493d3b0591SJens Wiklander #elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
503d3b0591SJens Wiklander     (__TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3)
aria_p1(uint32_t x)513d3b0591SJens Wiklander static inline uint32_t aria_p1(uint32_t x)
523d3b0591SJens Wiklander {
533d3b0591SJens Wiklander     uint32_t r;
543d3b0591SJens Wiklander     __asm("rev16 r, x");
5532b31808SJens Wiklander     return r;
563d3b0591SJens Wiklander }
573d3b0591SJens Wiklander #define ARIA_P1 aria_p1
583d3b0591SJens Wiklander #endif
593d3b0591SJens Wiklander #endif /* arm */
603d3b0591SJens Wiklander #if defined(__GNUC__) && \
613d3b0591SJens Wiklander     defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
623d3b0591SJens Wiklander /* I couldn't find an Intel equivalent of rev16, so two instructions */
633d3b0591SJens Wiklander #define ARIA_P1(x) ARIA_P2(ARIA_P3(x))
643d3b0591SJens Wiklander #endif /* x86 gnuc */
653d3b0591SJens Wiklander #endif /* MBEDTLS_HAVE_ASM && GNUC */
663d3b0591SJens Wiklander #if !defined(ARIA_P1)
673d3b0591SJens Wiklander #define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
683d3b0591SJens Wiklander #endif
693d3b0591SJens Wiklander 
703d3b0591SJens Wiklander /*
713d3b0591SJens Wiklander  * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
723d3b0591SJens Wiklander  *
733d3b0591SJens Wiklander  * This is submatrix P2 in [1] Appendix B.1
743d3b0591SJens Wiklander  *
753d3b0591SJens Wiklander  * Common compilers will translate this to a single instruction.
763d3b0591SJens Wiklander  */
773d3b0591SJens Wiklander #define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
783d3b0591SJens Wiklander 
793d3b0591SJens Wiklander /*
803d3b0591SJens Wiklander  * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
813d3b0591SJens Wiklander  *
823d3b0591SJens Wiklander  * This is submatrix P3 in [1] Appendix B.1
833d3b0591SJens Wiklander  */
8432b31808SJens Wiklander #define ARIA_P3(x) MBEDTLS_BSWAP32(x)
853d3b0591SJens Wiklander 
863d3b0591SJens Wiklander /*
873d3b0591SJens Wiklander  * ARIA Affine Transform
883d3b0591SJens Wiklander  * (a, b, c, d) = state in/out
893d3b0591SJens Wiklander  *
903d3b0591SJens Wiklander  * If we denote the first byte of input by 0, ..., the last byte by f,
913d3b0591SJens Wiklander  * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
923d3b0591SJens Wiklander  *
933d3b0591SJens Wiklander  * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple
943d3b0591SJens Wiklander  * rearrangements on adjacent pairs, output is:
953d3b0591SJens Wiklander  *
963d3b0591SJens Wiklander  * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
973d3b0591SJens Wiklander  *   = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
983d3b0591SJens Wiklander  * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd
993d3b0591SJens Wiklander  *   = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
1003d3b0591SJens Wiklander  * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe
1013d3b0591SJens Wiklander  *   = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
1023d3b0591SJens Wiklander  * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef
1033d3b0591SJens Wiklander  *   = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
1043d3b0591SJens Wiklander  *
1053d3b0591SJens Wiklander  * Note: another presentation of the A transform can be found as the first
1063d3b0591SJens Wiklander  * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
1073d3b0591SJens Wiklander  * The implementation below uses only P1 and P2 as they are sufficient.
1083d3b0591SJens Wiklander  */
aria_a(uint32_t * a,uint32_t * b,uint32_t * c,uint32_t * d)1093d3b0591SJens Wiklander static inline void aria_a(uint32_t *a, uint32_t *b,
1103d3b0591SJens Wiklander                           uint32_t *c, uint32_t *d)
1113d3b0591SJens Wiklander {
1123d3b0591SJens Wiklander     uint32_t ta, tb, tc;
1133d3b0591SJens Wiklander     ta  =  *b;                      // 4567
1143d3b0591SJens Wiklander     *b  =  *a;                      // 0123
1153d3b0591SJens Wiklander     *a  =  ARIA_P2(ta);             // 6745
1163d3b0591SJens Wiklander     tb  =  ARIA_P2(*d);             // efcd
1173d3b0591SJens Wiklander     *d  =  ARIA_P1(*c);             // 98ba
1183d3b0591SJens Wiklander     *c  =  ARIA_P1(tb);             // fedc
1193d3b0591SJens Wiklander     ta  ^= *d;                      // 4567+98ba
1203d3b0591SJens Wiklander     tc  =  ARIA_P2(*b);             // 2301
1213d3b0591SJens Wiklander     ta  =  ARIA_P1(ta) ^ tc ^ *c;   // 2301+5476+89ab+fedc
1223d3b0591SJens Wiklander     tb  ^= ARIA_P2(*d);             // ba98+efcd
1233d3b0591SJens Wiklander     tc  ^= ARIA_P1(*a);             // 2301+7654
1243d3b0591SJens Wiklander     *b  ^= ta ^ tb;                 // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
1253d3b0591SJens Wiklander     tb  =  ARIA_P2(tb) ^ ta;        // 2301+5476+89ab+98ba+cdef+fedc
1263d3b0591SJens Wiklander     *a  ^= ARIA_P1(tb);             // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
1273d3b0591SJens Wiklander     ta  =  ARIA_P2(ta);             // 0123+7654+ab89+dcfe
1283d3b0591SJens Wiklander     *d  ^= ARIA_P1(ta) ^ tc;        // 1032+2301+6745+7654+98ba+ba98+cdef OUT
1293d3b0591SJens Wiklander     tc  =  ARIA_P2(tc);             // 0123+5476
1303d3b0591SJens Wiklander     *c  ^= ARIA_P1(tc) ^ ta;        // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
1313d3b0591SJens Wiklander }
1323d3b0591SJens Wiklander 
1333d3b0591SJens Wiklander /*
1343d3b0591SJens Wiklander  * ARIA Substitution Layer SL1 / SL2
1353d3b0591SJens Wiklander  * (a, b, c, d) = state in/out
1363d3b0591SJens Wiklander  * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
1373d3b0591SJens Wiklander  *
1383d3b0591SJens Wiklander  * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
1393d3b0591SJens Wiklander  * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
1403d3b0591SJens Wiklander  */
aria_sl(uint32_t * a,uint32_t * b,uint32_t * c,uint32_t * d,const uint8_t sa[256],const uint8_t sb[256],const uint8_t sc[256],const uint8_t sd[256])1413d3b0591SJens Wiklander static inline void aria_sl(uint32_t *a, uint32_t *b,
1423d3b0591SJens Wiklander                            uint32_t *c, uint32_t *d,
1433d3b0591SJens Wiklander                            const uint8_t sa[256], const uint8_t sb[256],
1443d3b0591SJens Wiklander                            const uint8_t sc[256], const uint8_t sd[256])
1453d3b0591SJens Wiklander {
146039e02dfSJerome Forissier     *a = ((uint32_t) sa[MBEDTLS_BYTE_0(*a)]) ^
147039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*a)]) <<  8) ^
148039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*a)]) << 16) ^
149039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*a)]) << 24);
150039e02dfSJerome Forissier     *b = ((uint32_t) sa[MBEDTLS_BYTE_0(*b)]) ^
151039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*b)]) <<  8) ^
152039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*b)]) << 16) ^
153039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*b)]) << 24);
154039e02dfSJerome Forissier     *c = ((uint32_t) sa[MBEDTLS_BYTE_0(*c)]) ^
155039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*c)]) <<  8) ^
156039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*c)]) << 16) ^
157039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*c)]) << 24);
158039e02dfSJerome Forissier     *d = ((uint32_t) sa[MBEDTLS_BYTE_0(*d)]) ^
159039e02dfSJerome Forissier          (((uint32_t) sb[MBEDTLS_BYTE_1(*d)]) <<  8) ^
160039e02dfSJerome Forissier          (((uint32_t) sc[MBEDTLS_BYTE_2(*d)]) << 16) ^
161039e02dfSJerome Forissier          (((uint32_t) sd[MBEDTLS_BYTE_3(*d)]) << 24);
1623d3b0591SJens Wiklander }
1633d3b0591SJens Wiklander 
1643d3b0591SJens Wiklander /*
1653d3b0591SJens Wiklander  * S-Boxes
1663d3b0591SJens Wiklander  */
1673d3b0591SJens Wiklander static const uint8_t aria_sb1[256] =
1683d3b0591SJens Wiklander {
1693d3b0591SJens Wiklander     0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
1703d3b0591SJens Wiklander     0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
1713d3b0591SJens Wiklander     0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
1723d3b0591SJens Wiklander     0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
1733d3b0591SJens Wiklander     0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
1743d3b0591SJens Wiklander     0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
1753d3b0591SJens Wiklander     0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
1763d3b0591SJens Wiklander     0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
1773d3b0591SJens Wiklander     0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
1783d3b0591SJens Wiklander     0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
1793d3b0591SJens Wiklander     0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
1803d3b0591SJens Wiklander     0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
1813d3b0591SJens Wiklander     0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
1823d3b0591SJens Wiklander     0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
1833d3b0591SJens Wiklander     0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
1843d3b0591SJens Wiklander     0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
1853d3b0591SJens Wiklander     0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
1863d3b0591SJens Wiklander     0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
1873d3b0591SJens Wiklander     0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
1883d3b0591SJens Wiklander     0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
1893d3b0591SJens Wiklander     0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
1903d3b0591SJens Wiklander     0xB0, 0x54, 0xBB, 0x16
1913d3b0591SJens Wiklander };
1923d3b0591SJens Wiklander 
1933d3b0591SJens Wiklander static const uint8_t aria_sb2[256] =
1943d3b0591SJens Wiklander {
1953d3b0591SJens Wiklander     0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
1963d3b0591SJens Wiklander     0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
1973d3b0591SJens Wiklander     0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
1983d3b0591SJens Wiklander     0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
1993d3b0591SJens Wiklander     0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
2003d3b0591SJens Wiklander     0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
2013d3b0591SJens Wiklander     0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
2023d3b0591SJens Wiklander     0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
2033d3b0591SJens Wiklander     0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
2043d3b0591SJens Wiklander     0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
2053d3b0591SJens Wiklander     0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
2063d3b0591SJens Wiklander     0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
2073d3b0591SJens Wiklander     0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
2083d3b0591SJens Wiklander     0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
2093d3b0591SJens Wiklander     0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
2103d3b0591SJens Wiklander     0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
2113d3b0591SJens Wiklander     0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
2123d3b0591SJens Wiklander     0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
2133d3b0591SJens Wiklander     0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
2143d3b0591SJens Wiklander     0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
2153d3b0591SJens Wiklander     0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
2163d3b0591SJens Wiklander     0xAF, 0xBA, 0xB5, 0x81
2173d3b0591SJens Wiklander };
2183d3b0591SJens Wiklander 
2193d3b0591SJens Wiklander static const uint8_t aria_is1[256] =
2203d3b0591SJens Wiklander {
2213d3b0591SJens Wiklander     0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
2223d3b0591SJens Wiklander     0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
2233d3b0591SJens Wiklander     0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
2243d3b0591SJens Wiklander     0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
2253d3b0591SJens Wiklander     0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
2263d3b0591SJens Wiklander     0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
2273d3b0591SJens Wiklander     0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
2283d3b0591SJens Wiklander     0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
2293d3b0591SJens Wiklander     0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
2303d3b0591SJens Wiklander     0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
2313d3b0591SJens Wiklander     0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
2323d3b0591SJens Wiklander     0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
2333d3b0591SJens Wiklander     0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
2343d3b0591SJens Wiklander     0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
2353d3b0591SJens Wiklander     0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
2363d3b0591SJens Wiklander     0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
2373d3b0591SJens Wiklander     0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
2383d3b0591SJens Wiklander     0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
2393d3b0591SJens Wiklander     0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
2403d3b0591SJens Wiklander     0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
2413d3b0591SJens Wiklander     0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
2423d3b0591SJens Wiklander     0x55, 0x21, 0x0C, 0x7D
2433d3b0591SJens Wiklander };
2443d3b0591SJens Wiklander 
2453d3b0591SJens Wiklander static const uint8_t aria_is2[256] =
2463d3b0591SJens Wiklander {
2473d3b0591SJens Wiklander     0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
2483d3b0591SJens Wiklander     0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
2493d3b0591SJens Wiklander     0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
2503d3b0591SJens Wiklander     0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
2513d3b0591SJens Wiklander     0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
2523d3b0591SJens Wiklander     0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
2533d3b0591SJens Wiklander     0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
2543d3b0591SJens Wiklander     0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
2553d3b0591SJens Wiklander     0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
2563d3b0591SJens Wiklander     0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
2573d3b0591SJens Wiklander     0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
2583d3b0591SJens Wiklander     0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
2593d3b0591SJens Wiklander     0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
2603d3b0591SJens Wiklander     0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
2613d3b0591SJens Wiklander     0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
2623d3b0591SJens Wiklander     0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
2633d3b0591SJens Wiklander     0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
2643d3b0591SJens Wiklander     0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
2653d3b0591SJens Wiklander     0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
2663d3b0591SJens Wiklander     0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
2673d3b0591SJens Wiklander     0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
2683d3b0591SJens Wiklander     0x03, 0xA2, 0xAC, 0x60
2693d3b0591SJens Wiklander };
2703d3b0591SJens Wiklander 
2713d3b0591SJens Wiklander /*
2723d3b0591SJens Wiklander  * Helper for key schedule: r = FO( p, k ) ^ x
2733d3b0591SJens Wiklander  */
aria_fo_xor(uint32_t r[4],const uint32_t p[4],const uint32_t k[4],const uint32_t x[4])2743d3b0591SJens Wiklander static void aria_fo_xor(uint32_t r[4], const uint32_t p[4],
2753d3b0591SJens Wiklander                         const uint32_t k[4], const uint32_t x[4])
2763d3b0591SJens Wiklander {
2773d3b0591SJens Wiklander     uint32_t a, b, c, d;
2783d3b0591SJens Wiklander 
2793d3b0591SJens Wiklander     a = p[0] ^ k[0];
2803d3b0591SJens Wiklander     b = p[1] ^ k[1];
2813d3b0591SJens Wiklander     c = p[2] ^ k[2];
2823d3b0591SJens Wiklander     d = p[3] ^ k[3];
2833d3b0591SJens Wiklander 
2843d3b0591SJens Wiklander     aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2);
2853d3b0591SJens Wiklander     aria_a(&a, &b, &c, &d);
2863d3b0591SJens Wiklander 
2873d3b0591SJens Wiklander     r[0] = a ^ x[0];
2883d3b0591SJens Wiklander     r[1] = b ^ x[1];
2893d3b0591SJens Wiklander     r[2] = c ^ x[2];
2903d3b0591SJens Wiklander     r[3] = d ^ x[3];
2913d3b0591SJens Wiklander }
2923d3b0591SJens Wiklander 
2933d3b0591SJens Wiklander /*
2943d3b0591SJens Wiklander  * Helper for key schedule: r = FE( p, k ) ^ x
2953d3b0591SJens Wiklander  */
aria_fe_xor(uint32_t r[4],const uint32_t p[4],const uint32_t k[4],const uint32_t x[4])2963d3b0591SJens Wiklander static void aria_fe_xor(uint32_t r[4], const uint32_t p[4],
2973d3b0591SJens Wiklander                         const uint32_t k[4], const uint32_t x[4])
2983d3b0591SJens Wiklander {
2993d3b0591SJens Wiklander     uint32_t a, b, c, d;
3003d3b0591SJens Wiklander 
3013d3b0591SJens Wiklander     a = p[0] ^ k[0];
3023d3b0591SJens Wiklander     b = p[1] ^ k[1];
3033d3b0591SJens Wiklander     c = p[2] ^ k[2];
3043d3b0591SJens Wiklander     d = p[3] ^ k[3];
3053d3b0591SJens Wiklander 
3063d3b0591SJens Wiklander     aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2);
3073d3b0591SJens Wiklander     aria_a(&a, &b, &c, &d);
3083d3b0591SJens Wiklander 
3093d3b0591SJens Wiklander     r[0] = a ^ x[0];
3103d3b0591SJens Wiklander     r[1] = b ^ x[1];
3113d3b0591SJens Wiklander     r[2] = c ^ x[2];
3123d3b0591SJens Wiklander     r[3] = d ^ x[3];
3133d3b0591SJens Wiklander }
3143d3b0591SJens Wiklander 
3153d3b0591SJens Wiklander /*
3163d3b0591SJens Wiklander  * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
3173d3b0591SJens Wiklander  *
3183d3b0591SJens Wiklander  * We chose to store bytes into 32-bit words in little-endian format (see
319039e02dfSJerome Forissier  * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse
320039e02dfSJerome Forissier  * bytes here.
3213d3b0591SJens Wiklander  */
aria_rot128(uint32_t r[4],const uint32_t a[4],const uint32_t b[4],uint8_t n)3223d3b0591SJens Wiklander static void aria_rot128(uint32_t r[4], const uint32_t a[4],
3233d3b0591SJens Wiklander                         const uint32_t b[4], uint8_t n)
3243d3b0591SJens Wiklander {
3253d3b0591SJens Wiklander     uint8_t i, j;
3263d3b0591SJens Wiklander     uint32_t t, u;
3273d3b0591SJens Wiklander 
3283d3b0591SJens Wiklander     const uint8_t n1 = n % 32;              // bit offset
3293d3b0591SJens Wiklander     const uint8_t n2 = n1 ? 32 - n1 : 0;    // reverse bit offset
3303d3b0591SJens Wiklander 
3313d3b0591SJens Wiklander     j = (n / 32) % 4;                       // initial word offset
3323d3b0591SJens Wiklander     t = ARIA_P3(b[j]);                      // big endian
33332b31808SJens Wiklander     for (i = 0; i < 4; i++) {
3343d3b0591SJens Wiklander         j = (j + 1) % 4;                    // get next word, big endian
3353d3b0591SJens Wiklander         u = ARIA_P3(b[j]);
3363d3b0591SJens Wiklander         t <<= n1;                           // rotate
3373d3b0591SJens Wiklander         t |= u >> n2;
3383d3b0591SJens Wiklander         t = ARIA_P3(t);                     // back to little endian
3393d3b0591SJens Wiklander         r[i] = a[i] ^ t;                    // store
3403d3b0591SJens Wiklander         t = u;                              // move to next word
3413d3b0591SJens Wiklander     }
3423d3b0591SJens Wiklander }
3433d3b0591SJens Wiklander 
3443d3b0591SJens Wiklander /*
3453d3b0591SJens Wiklander  * Set encryption key
3463d3b0591SJens Wiklander  */
mbedtls_aria_setkey_enc(mbedtls_aria_context * ctx,const unsigned char * key,unsigned int keybits)3473d3b0591SJens Wiklander int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
3483d3b0591SJens Wiklander                             const unsigned char *key, unsigned int keybits)
3493d3b0591SJens Wiklander {
3503d3b0591SJens Wiklander     /* round constant masks */
3513d3b0591SJens Wiklander     const uint32_t rc[3][4] =
3523d3b0591SJens Wiklander     {
3533d3b0591SJens Wiklander         {   0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA  },
3543d3b0591SJens Wiklander         {   0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF  },
3553d3b0591SJens Wiklander         {   0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804  }
3563d3b0591SJens Wiklander     };
3573d3b0591SJens Wiklander 
3583d3b0591SJens Wiklander     int i;
3593d3b0591SJens Wiklander     uint32_t w[4][4], *w2;
3603d3b0591SJens Wiklander 
36132b31808SJens Wiklander     if (keybits != 128 && keybits != 192 && keybits != 256) {
36232b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
36332b31808SJens Wiklander     }
3643d3b0591SJens Wiklander 
3653d3b0591SJens Wiklander     /* Copy key to W0 (and potential remainder to W1) */
366039e02dfSJerome Forissier     w[0][0] = MBEDTLS_GET_UINT32_LE(key,  0);
367039e02dfSJerome Forissier     w[0][1] = MBEDTLS_GET_UINT32_LE(key,  4);
368039e02dfSJerome Forissier     w[0][2] = MBEDTLS_GET_UINT32_LE(key,  8);
369039e02dfSJerome Forissier     w[0][3] = MBEDTLS_GET_UINT32_LE(key, 12);
3703d3b0591SJens Wiklander 
3713d3b0591SJens Wiklander     memset(w[1], 0, 16);
37232b31808SJens Wiklander     if (keybits >= 192) {
373039e02dfSJerome Forissier         w[1][0] = MBEDTLS_GET_UINT32_LE(key, 16);    // 192 bit key
374039e02dfSJerome Forissier         w[1][1] = MBEDTLS_GET_UINT32_LE(key, 20);
3753d3b0591SJens Wiklander     }
37632b31808SJens Wiklander     if (keybits == 256) {
377039e02dfSJerome Forissier         w[1][2] = MBEDTLS_GET_UINT32_LE(key, 24);    // 256 bit key
378039e02dfSJerome Forissier         w[1][3] = MBEDTLS_GET_UINT32_LE(key, 28);
3793d3b0591SJens Wiklander     }
3803d3b0591SJens Wiklander 
3813d3b0591SJens Wiklander     i = (keybits - 128) >> 6;               // index: 0, 1, 2
3823d3b0591SJens Wiklander     ctx->nr = 12 + 2 * i;                   // no. rounds: 12, 14, 16
3833d3b0591SJens Wiklander 
3843d3b0591SJens Wiklander     aria_fo_xor(w[1], w[0], rc[i], w[1]);   // W1 = FO(W0, CK1) ^ KR
3853d3b0591SJens Wiklander     i = i < 2 ? i + 1 : 0;
3863d3b0591SJens Wiklander     aria_fe_xor(w[2], w[1], rc[i], w[0]);   // W2 = FE(W1, CK2) ^ W0
3873d3b0591SJens Wiklander     i = i < 2 ? i + 1 : 0;
3883d3b0591SJens Wiklander     aria_fo_xor(w[3], w[2], rc[i], w[1]);   // W3 = FO(W2, CK3) ^ W1
3893d3b0591SJens Wiklander 
39032b31808SJens Wiklander     for (i = 0; i < 4; i++) {               // create round keys
3913d3b0591SJens Wiklander         w2 = w[(i + 1) & 3];
3923d3b0591SJens Wiklander         aria_rot128(ctx->rk[i], w[i], w2, 128 - 19);
3933d3b0591SJens Wiklander         aria_rot128(ctx->rk[i +  4], w[i], w2, 128 - 31);
3943d3b0591SJens Wiklander         aria_rot128(ctx->rk[i +  8], w[i], w2,       61);
3953d3b0591SJens Wiklander         aria_rot128(ctx->rk[i + 12], w[i], w2,       31);
3963d3b0591SJens Wiklander     }
3973d3b0591SJens Wiklander     aria_rot128(ctx->rk[16], w[0], w[1], 19);
3983d3b0591SJens Wiklander 
3993d3b0591SJens Wiklander     /* w holds enough info to reconstruct the round keys */
4003d3b0591SJens Wiklander     mbedtls_platform_zeroize(w, sizeof(w));
4013d3b0591SJens Wiklander 
40232b31808SJens Wiklander     return 0;
4033d3b0591SJens Wiklander }
4043d3b0591SJens Wiklander 
4053d3b0591SJens Wiklander /*
4063d3b0591SJens Wiklander  * Set decryption key
4073d3b0591SJens Wiklander  */
408*b0563631STom Van Eyck #if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
mbedtls_aria_setkey_dec(mbedtls_aria_context * ctx,const unsigned char * key,unsigned int keybits)4093d3b0591SJens Wiklander int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
4103d3b0591SJens Wiklander                             const unsigned char *key, unsigned int keybits)
4113d3b0591SJens Wiklander {
4123d3b0591SJens Wiklander     int i, j, k, ret;
4133d3b0591SJens Wiklander 
4143d3b0591SJens Wiklander     ret = mbedtls_aria_setkey_enc(ctx, key, keybits);
41532b31808SJens Wiklander     if (ret != 0) {
41632b31808SJens Wiklander         return ret;
41732b31808SJens Wiklander     }
4183d3b0591SJens Wiklander 
4193d3b0591SJens Wiklander     /* flip the order of round keys */
42032b31808SJens Wiklander     for (i = 0, j = ctx->nr; i < j; i++, j--) {
42132b31808SJens Wiklander         for (k = 0; k < 4; k++) {
4223d3b0591SJens Wiklander             uint32_t t = ctx->rk[i][k];
4233d3b0591SJens Wiklander             ctx->rk[i][k] = ctx->rk[j][k];
4243d3b0591SJens Wiklander             ctx->rk[j][k] = t;
4253d3b0591SJens Wiklander         }
4263d3b0591SJens Wiklander     }
4273d3b0591SJens Wiklander 
4283d3b0591SJens Wiklander     /* apply affine transform to middle keys */
42932b31808SJens Wiklander     for (i = 1; i < ctx->nr; i++) {
4303d3b0591SJens Wiklander         aria_a(&ctx->rk[i][0], &ctx->rk[i][1],
4313d3b0591SJens Wiklander                &ctx->rk[i][2], &ctx->rk[i][3]);
4323d3b0591SJens Wiklander     }
4333d3b0591SJens Wiklander 
43432b31808SJens Wiklander     return 0;
4353d3b0591SJens Wiklander }
436*b0563631STom Van Eyck #endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
4373d3b0591SJens Wiklander 
4383d3b0591SJens Wiklander /*
4393d3b0591SJens Wiklander  * Encrypt a block
4403d3b0591SJens Wiklander  */
mbedtls_aria_crypt_ecb(mbedtls_aria_context * ctx,const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],unsigned char output[MBEDTLS_ARIA_BLOCKSIZE])4413d3b0591SJens Wiklander int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
4423d3b0591SJens Wiklander                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
4433d3b0591SJens Wiklander                            unsigned char output[MBEDTLS_ARIA_BLOCKSIZE])
4443d3b0591SJens Wiklander {
4453d3b0591SJens Wiklander     int i;
4463d3b0591SJens Wiklander 
4473d3b0591SJens Wiklander     uint32_t a, b, c, d;
4483d3b0591SJens Wiklander 
449039e02dfSJerome Forissier     a = MBEDTLS_GET_UINT32_LE(input,  0);
450039e02dfSJerome Forissier     b = MBEDTLS_GET_UINT32_LE(input,  4);
451039e02dfSJerome Forissier     c = MBEDTLS_GET_UINT32_LE(input,  8);
452039e02dfSJerome Forissier     d = MBEDTLS_GET_UINT32_LE(input, 12);
4533d3b0591SJens Wiklander 
4543d3b0591SJens Wiklander     i = 0;
45532b31808SJens Wiklander     while (1) {
4563d3b0591SJens Wiklander         a ^= ctx->rk[i][0];
4573d3b0591SJens Wiklander         b ^= ctx->rk[i][1];
4583d3b0591SJens Wiklander         c ^= ctx->rk[i][2];
4593d3b0591SJens Wiklander         d ^= ctx->rk[i][3];
4603d3b0591SJens Wiklander         i++;
4613d3b0591SJens Wiklander 
4623d3b0591SJens Wiklander         aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2);
4633d3b0591SJens Wiklander         aria_a(&a, &b, &c, &d);
4643d3b0591SJens Wiklander 
4653d3b0591SJens Wiklander         a ^= ctx->rk[i][0];
4663d3b0591SJens Wiklander         b ^= ctx->rk[i][1];
4673d3b0591SJens Wiklander         c ^= ctx->rk[i][2];
4683d3b0591SJens Wiklander         d ^= ctx->rk[i][3];
4693d3b0591SJens Wiklander         i++;
4703d3b0591SJens Wiklander 
4713d3b0591SJens Wiklander         aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2);
47232b31808SJens Wiklander         if (i >= ctx->nr) {
4733d3b0591SJens Wiklander             break;
47432b31808SJens Wiklander         }
4753d3b0591SJens Wiklander         aria_a(&a, &b, &c, &d);
4763d3b0591SJens Wiklander     }
4773d3b0591SJens Wiklander 
4783d3b0591SJens Wiklander     /* final key mixing */
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 
484039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(a, output,  0);
485039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(b, output,  4);
486039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(c, output,  8);
487039e02dfSJerome Forissier     MBEDTLS_PUT_UINT32_LE(d, output, 12);
4883d3b0591SJens Wiklander 
48932b31808SJens Wiklander     return 0;
4903d3b0591SJens Wiklander }
4913d3b0591SJens Wiklander 
4923d3b0591SJens Wiklander /* Initialize context */
mbedtls_aria_init(mbedtls_aria_context * ctx)4933d3b0591SJens Wiklander void mbedtls_aria_init(mbedtls_aria_context *ctx)
4943d3b0591SJens Wiklander {
4953d3b0591SJens Wiklander     memset(ctx, 0, sizeof(mbedtls_aria_context));
4963d3b0591SJens Wiklander }
4973d3b0591SJens Wiklander 
4983d3b0591SJens Wiklander /* Clear context */
mbedtls_aria_free(mbedtls_aria_context * ctx)4993d3b0591SJens Wiklander void mbedtls_aria_free(mbedtls_aria_context *ctx)
5003d3b0591SJens Wiklander {
50132b31808SJens Wiklander     if (ctx == NULL) {
5023d3b0591SJens Wiklander         return;
50332b31808SJens Wiklander     }
5043d3b0591SJens Wiklander 
5053d3b0591SJens Wiklander     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aria_context));
5063d3b0591SJens Wiklander }
5073d3b0591SJens Wiklander 
5083d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
5093d3b0591SJens Wiklander /*
5103d3b0591SJens Wiklander  * ARIA-CBC buffer encryption/decryption
5113d3b0591SJens Wiklander  */
mbedtls_aria_crypt_cbc(mbedtls_aria_context * ctx,int mode,size_t length,unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],const unsigned char * input,unsigned char * output)5123d3b0591SJens Wiklander int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
5133d3b0591SJens Wiklander                            int mode,
5143d3b0591SJens Wiklander                            size_t length,
5153d3b0591SJens Wiklander                            unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
5163d3b0591SJens Wiklander                            const unsigned char *input,
5173d3b0591SJens Wiklander                            unsigned char *output)
5183d3b0591SJens Wiklander {
5193d3b0591SJens Wiklander     unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
5203d3b0591SJens Wiklander 
521*b0563631STom Van Eyck     if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) {
522*b0563631STom Van Eyck         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
523*b0563631STom Van Eyck     }
5243d3b0591SJens Wiklander 
52532b31808SJens Wiklander     if (length % MBEDTLS_ARIA_BLOCKSIZE) {
52632b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH;
52732b31808SJens Wiklander     }
5283d3b0591SJens Wiklander 
52932b31808SJens Wiklander     if (mode == MBEDTLS_ARIA_DECRYPT) {
53032b31808SJens Wiklander         while (length > 0) {
5313d3b0591SJens Wiklander             memcpy(temp, input, MBEDTLS_ARIA_BLOCKSIZE);
5323d3b0591SJens Wiklander             mbedtls_aria_crypt_ecb(ctx, input, output);
5333d3b0591SJens Wiklander 
53432b31808SJens Wiklander             mbedtls_xor(output, output, iv, MBEDTLS_ARIA_BLOCKSIZE);
5353d3b0591SJens Wiklander 
5363d3b0591SJens Wiklander             memcpy(iv, temp, MBEDTLS_ARIA_BLOCKSIZE);
5373d3b0591SJens Wiklander 
5383d3b0591SJens Wiklander             input  += MBEDTLS_ARIA_BLOCKSIZE;
5393d3b0591SJens Wiklander             output += MBEDTLS_ARIA_BLOCKSIZE;
5403d3b0591SJens Wiklander             length -= MBEDTLS_ARIA_BLOCKSIZE;
5413d3b0591SJens Wiklander         }
54232b31808SJens Wiklander     } else {
54332b31808SJens Wiklander         while (length > 0) {
54432b31808SJens Wiklander             mbedtls_xor(output, input, iv, MBEDTLS_ARIA_BLOCKSIZE);
5453d3b0591SJens Wiklander 
5463d3b0591SJens Wiklander             mbedtls_aria_crypt_ecb(ctx, output, output);
5473d3b0591SJens Wiklander             memcpy(iv, output, MBEDTLS_ARIA_BLOCKSIZE);
5483d3b0591SJens Wiklander 
5493d3b0591SJens Wiklander             input  += MBEDTLS_ARIA_BLOCKSIZE;
5503d3b0591SJens Wiklander             output += MBEDTLS_ARIA_BLOCKSIZE;
5513d3b0591SJens Wiklander             length -= MBEDTLS_ARIA_BLOCKSIZE;
5523d3b0591SJens Wiklander         }
5533d3b0591SJens Wiklander     }
5543d3b0591SJens Wiklander 
55532b31808SJens Wiklander     return 0;
5563d3b0591SJens Wiklander }
5573d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
5583d3b0591SJens Wiklander 
5593d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
5603d3b0591SJens Wiklander /*
5613d3b0591SJens Wiklander  * ARIA-CFB128 buffer encryption/decryption
5623d3b0591SJens Wiklander  */
mbedtls_aria_crypt_cfb128(mbedtls_aria_context * ctx,int mode,size_t length,size_t * iv_off,unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],const unsigned char * input,unsigned char * output)5633d3b0591SJens Wiklander int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
5643d3b0591SJens Wiklander                               int mode,
5653d3b0591SJens Wiklander                               size_t length,
5663d3b0591SJens Wiklander                               size_t *iv_off,
5673d3b0591SJens Wiklander                               unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
5683d3b0591SJens Wiklander                               const unsigned char *input,
5693d3b0591SJens Wiklander                               unsigned char *output)
5703d3b0591SJens Wiklander {
5713d3b0591SJens Wiklander     unsigned char c;
5723d3b0591SJens Wiklander     size_t n;
5733d3b0591SJens Wiklander 
574*b0563631STom Van Eyck     if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) {
575*b0563631STom Van Eyck         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
576*b0563631STom Van Eyck     }
5773d3b0591SJens Wiklander 
5783d3b0591SJens Wiklander     n = *iv_off;
5793d3b0591SJens Wiklander 
5803d3b0591SJens Wiklander     /* An overly large value of n can lead to an unlimited
581*b0563631STom Van Eyck      * buffer overflow. */
58232b31808SJens Wiklander     if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
58332b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
58432b31808SJens Wiklander     }
5853d3b0591SJens Wiklander 
58632b31808SJens Wiklander     if (mode == MBEDTLS_ARIA_DECRYPT) {
58732b31808SJens Wiklander         while (length--) {
58832b31808SJens Wiklander             if (n == 0) {
5893d3b0591SJens Wiklander                 mbedtls_aria_crypt_ecb(ctx, iv, iv);
59032b31808SJens Wiklander             }
5913d3b0591SJens Wiklander 
5923d3b0591SJens Wiklander             c = *input++;
5933d3b0591SJens Wiklander             *output++ = c ^ iv[n];
5943d3b0591SJens Wiklander             iv[n] = c;
5953d3b0591SJens Wiklander 
5963d3b0591SJens Wiklander             n = (n + 1) & 0x0F;
5973d3b0591SJens Wiklander         }
59832b31808SJens Wiklander     } else {
59932b31808SJens Wiklander         while (length--) {
60032b31808SJens Wiklander             if (n == 0) {
6013d3b0591SJens Wiklander                 mbedtls_aria_crypt_ecb(ctx, iv, iv);
60232b31808SJens Wiklander             }
6033d3b0591SJens Wiklander 
6043d3b0591SJens Wiklander             iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
6053d3b0591SJens Wiklander 
6063d3b0591SJens Wiklander             n = (n + 1) & 0x0F;
6073d3b0591SJens Wiklander         }
6083d3b0591SJens Wiklander     }
6093d3b0591SJens Wiklander 
6103d3b0591SJens Wiklander     *iv_off = n;
6113d3b0591SJens Wiklander 
61232b31808SJens Wiklander     return 0;
6133d3b0591SJens Wiklander }
6143d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
6153d3b0591SJens Wiklander 
6163d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
6173d3b0591SJens Wiklander /*
6183d3b0591SJens Wiklander  * ARIA-CTR buffer encryption/decryption
6193d3b0591SJens Wiklander  */
mbedtls_aria_crypt_ctr(mbedtls_aria_context * ctx,size_t length,size_t * nc_off,unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],const unsigned char * input,unsigned char * output)6203d3b0591SJens Wiklander int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
6213d3b0591SJens Wiklander                            size_t length,
6223d3b0591SJens Wiklander                            size_t *nc_off,
6233d3b0591SJens Wiklander                            unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
6243d3b0591SJens Wiklander                            unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
6253d3b0591SJens Wiklander                            const unsigned char *input,
6263d3b0591SJens Wiklander                            unsigned char *output)
6273d3b0591SJens Wiklander {
6283d3b0591SJens Wiklander     int c, i;
6293d3b0591SJens Wiklander     size_t n;
6303d3b0591SJens Wiklander 
6313d3b0591SJens Wiklander     n = *nc_off;
6323d3b0591SJens Wiklander     /* An overly large value of n can lead to an unlimited
633*b0563631STom Van Eyck      * buffer overflow. */
63432b31808SJens Wiklander     if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
63532b31808SJens Wiklander         return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
63632b31808SJens Wiklander     }
6373d3b0591SJens Wiklander 
63832b31808SJens Wiklander     while (length--) {
6393d3b0591SJens Wiklander         if (n == 0) {
6403d3b0591SJens Wiklander             mbedtls_aria_crypt_ecb(ctx, nonce_counter,
6413d3b0591SJens Wiklander                                    stream_block);
6423d3b0591SJens Wiklander 
64332b31808SJens Wiklander             for (i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i--) {
64432b31808SJens Wiklander                 if (++nonce_counter[i - 1] != 0) {
6453d3b0591SJens Wiklander                     break;
6463d3b0591SJens Wiklander                 }
64732b31808SJens Wiklander             }
64832b31808SJens Wiklander         }
6493d3b0591SJens Wiklander         c = *input++;
6503d3b0591SJens Wiklander         *output++ = (unsigned char) (c ^ stream_block[n]);
6513d3b0591SJens Wiklander 
6523d3b0591SJens Wiklander         n = (n + 1) & 0x0F;
6533d3b0591SJens Wiklander     }
6543d3b0591SJens Wiklander 
6553d3b0591SJens Wiklander     *nc_off = n;
6563d3b0591SJens Wiklander 
65732b31808SJens Wiklander     return 0;
6583d3b0591SJens Wiklander }
6593d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
6603d3b0591SJens Wiklander #endif /* !MBEDTLS_ARIA_ALT */
6613d3b0591SJens Wiklander 
6623d3b0591SJens Wiklander #if defined(MBEDTLS_SELF_TEST)
6633d3b0591SJens Wiklander 
6643d3b0591SJens Wiklander /*
6653d3b0591SJens Wiklander  * Basic ARIA ECB test vectors from RFC 5794
6663d3b0591SJens Wiklander  */
6673d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_key[32] =           // test key
6683d3b0591SJens Wiklander {
6693d3b0591SJens Wiklander     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,     // 128 bit
6703d3b0591SJens Wiklander     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
6713d3b0591SJens Wiklander     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,     // 192 bit
6723d3b0591SJens Wiklander     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F      // 256 bit
6733d3b0591SJens Wiklander };
6743d3b0591SJens Wiklander 
6753d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] =            // plaintext
6763d3b0591SJens Wiklander {
6773d3b0591SJens Wiklander     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // same for all
6783d3b0591SJens Wiklander     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF      // key sizes
6793d3b0591SJens Wiklander };
6803d3b0591SJens Wiklander 
6813d3b0591SJens Wiklander static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] =         // ciphertext
6823d3b0591SJens Wiklander {
6833d3b0591SJens Wiklander     { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73,   // 128 bit
6843d3b0591SJens Wiklander       0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
6853d3b0591SJens Wiklander     { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA,   // 192 bit
6863d3b0591SJens Wiklander       0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
6873d3b0591SJens Wiklander     { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F,   // 256 bit
6883d3b0591SJens Wiklander       0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
6893d3b0591SJens Wiklander };
6903d3b0591SJens Wiklander 
6913d3b0591SJens Wiklander /*
6923d3b0591SJens Wiklander  * Mode tests from "Test Vectors for ARIA"  Version 1.0
6933d3b0591SJens Wiklander  * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
6943d3b0591SJens Wiklander  */
6953d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
6963d3b0591SJens Wiklander     defined(MBEDTLS_CIPHER_MODE_CTR))
6973d3b0591SJens Wiklander static const uint8_t aria_test2_key[32] =
6983d3b0591SJens Wiklander {
6993d3b0591SJens Wiklander     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 128 bit
7003d3b0591SJens Wiklander     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
7013d3b0591SJens Wiklander     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 192 bit
7023d3b0591SJens Wiklander     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff      // 256 bit
7033d3b0591SJens Wiklander };
7043d3b0591SJens Wiklander 
7053d3b0591SJens Wiklander static const uint8_t aria_test2_pt[48] =
7063d3b0591SJens Wiklander {
7073d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa,     // same for all
7083d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
7093d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
7103d3b0591SJens Wiklander     0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
7113d3b0591SJens Wiklander     0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
7123d3b0591SJens Wiklander     0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
7133d3b0591SJens Wiklander };
7143d3b0591SJens Wiklander #endif
7153d3b0591SJens Wiklander 
7163d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
7173d3b0591SJens Wiklander static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] =
7183d3b0591SJens Wiklander {
7193d3b0591SJens Wiklander     0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,     // same for CBC, CFB
7203d3b0591SJens Wiklander     0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0      // CTR has zero IV
7213d3b0591SJens Wiklander };
7223d3b0591SJens Wiklander #endif
7233d3b0591SJens Wiklander 
7243d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
7253d3b0591SJens Wiklander static const uint8_t aria_test2_cbc_ct[3][48] =         // CBC ciphertext
7263d3b0591SJens Wiklander {
7273d3b0591SJens Wiklander     { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10,   // 128-bit key
7283d3b0591SJens Wiklander       0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
7293d3b0591SJens Wiklander       0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
7303d3b0591SJens Wiklander       0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
7313d3b0591SJens Wiklander       0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
7323d3b0591SJens Wiklander       0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
7333d3b0591SJens Wiklander     { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c,   // 192-bit key
7343d3b0591SJens Wiklander       0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
7353d3b0591SJens Wiklander       0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
7363d3b0591SJens Wiklander       0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
7373d3b0591SJens Wiklander       0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
7383d3b0591SJens Wiklander       0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
7393d3b0591SJens Wiklander     { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1,   // 256-bit key
7403d3b0591SJens Wiklander       0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
7413d3b0591SJens Wiklander       0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
7423d3b0591SJens Wiklander       0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
7433d3b0591SJens Wiklander       0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
7443d3b0591SJens Wiklander       0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
7453d3b0591SJens Wiklander };
7463d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
7473d3b0591SJens Wiklander 
7483d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
7493d3b0591SJens Wiklander static const uint8_t aria_test2_cfb_ct[3][48] =         // CFB ciphertext
7503d3b0591SJens Wiklander {
7513d3b0591SJens Wiklander     { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38,   // 128-bit key
7523d3b0591SJens Wiklander       0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
7533d3b0591SJens Wiklander       0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
7543d3b0591SJens Wiklander       0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
7553d3b0591SJens Wiklander       0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
7563d3b0591SJens Wiklander       0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
7573d3b0591SJens Wiklander     { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54,   // 192-bit key
7583d3b0591SJens Wiklander       0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
7593d3b0591SJens Wiklander       0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
7603d3b0591SJens Wiklander       0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
7613d3b0591SJens Wiklander       0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
7623d3b0591SJens Wiklander       0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
7633d3b0591SJens Wiklander     { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2,   // 256-bit key
7643d3b0591SJens Wiklander       0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
7653d3b0591SJens Wiklander       0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
7663d3b0591SJens Wiklander       0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
7673d3b0591SJens Wiklander       0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
7683d3b0591SJens Wiklander       0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
7693d3b0591SJens Wiklander };
7703d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
7713d3b0591SJens Wiklander 
7723d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
7733d3b0591SJens Wiklander static const uint8_t aria_test2_ctr_ct[3][48] =         // CTR ciphertext
7743d3b0591SJens Wiklander {
7753d3b0591SJens Wiklander     { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c,   // 128-bit key
7763d3b0591SJens Wiklander       0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
7773d3b0591SJens Wiklander       0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
7783d3b0591SJens Wiklander       0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
7793d3b0591SJens Wiklander       0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
7803d3b0591SJens Wiklander       0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
7813d3b0591SJens Wiklander     { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19,   // 192-bit key
7823d3b0591SJens Wiklander       0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
7833d3b0591SJens Wiklander       0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
7843d3b0591SJens Wiklander       0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
7853d3b0591SJens Wiklander       0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
7863d3b0591SJens Wiklander       0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
7873d3b0591SJens Wiklander     { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17,   // 256-bit key
7883d3b0591SJens Wiklander       0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
7893d3b0591SJens Wiklander       0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
7903d3b0591SJens Wiklander       0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
7913d3b0591SJens Wiklander       0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
7923d3b0591SJens Wiklander       0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
7933d3b0591SJens Wiklander };
7943d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
7953d3b0591SJens Wiklander 
79632b31808SJens Wiklander #define ARIA_SELF_TEST_ASSERT(cond)                   \
79732b31808SJens Wiklander     do {                                            \
79832b31808SJens Wiklander         if (cond) {                                \
7993d3b0591SJens Wiklander             if (verbose)                           \
8003d3b0591SJens Wiklander             mbedtls_printf("failed\n");       \
8017901324dSJerome Forissier             goto exit;                              \
8023d3b0591SJens Wiklander         } else {                                    \
8033d3b0591SJens Wiklander             if (verbose)                           \
8043d3b0591SJens Wiklander             mbedtls_printf("passed\n");       \
80532b31808SJens Wiklander         }                                           \
80632b31808SJens Wiklander     } while (0)
8073d3b0591SJens Wiklander 
8083d3b0591SJens Wiklander /*
8093d3b0591SJens Wiklander  * Checkup routine
8103d3b0591SJens Wiklander  */
mbedtls_aria_self_test(int verbose)8113d3b0591SJens Wiklander int mbedtls_aria_self_test(int verbose)
8123d3b0591SJens Wiklander {
8133d3b0591SJens Wiklander     int i;
8143d3b0591SJens Wiklander     uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
8153d3b0591SJens Wiklander     mbedtls_aria_context ctx;
8167901324dSJerome Forissier     int ret = 1;
8173d3b0591SJens Wiklander 
8183d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
8193d3b0591SJens Wiklander     size_t j;
8203d3b0591SJens Wiklander #endif
8213d3b0591SJens Wiklander 
8223d3b0591SJens Wiklander #if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
8233d3b0591SJens Wiklander     defined(MBEDTLS_CIPHER_MODE_CFB) || \
8243d3b0591SJens Wiklander     defined(MBEDTLS_CIPHER_MODE_CTR))
8253d3b0591SJens Wiklander     uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
8263d3b0591SJens Wiklander #endif
8273d3b0591SJens Wiklander 
8287901324dSJerome Forissier     mbedtls_aria_init(&ctx);
8297901324dSJerome Forissier 
8303d3b0591SJens Wiklander     /*
8313d3b0591SJens Wiklander      * Test set 1
8323d3b0591SJens Wiklander      */
83332b31808SJens Wiklander     for (i = 0; i < 3; i++) {
8343d3b0591SJens Wiklander         /* test ECB encryption */
83532b31808SJens Wiklander         if (verbose) {
8363d3b0591SJens Wiklander             mbedtls_printf("  ARIA-ECB-%d (enc): ", 128 + 64 * i);
83732b31808SJens Wiklander         }
8383d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test1_ecb_key, 128 + 64 * i);
8393d3b0591SJens Wiklander         mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_pt, blk);
84032b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(
84132b31808SJens Wiklander             memcmp(blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE)
84232b31808SJens Wiklander             != 0);
8433d3b0591SJens Wiklander 
8443d3b0591SJens Wiklander         /* test ECB decryption */
84532b31808SJens Wiklander         if (verbose) {
8463d3b0591SJens Wiklander             mbedtls_printf("  ARIA-ECB-%d (dec): ", 128 + 64 * i);
847*b0563631STom Van Eyck #if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
848*b0563631STom Van Eyck             mbedtls_printf("skipped\n");
849*b0563631STom Van Eyck #endif
85032b31808SJens Wiklander         }
851*b0563631STom Van Eyck 
852*b0563631STom Van Eyck #if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
8533d3b0591SJens Wiklander         mbedtls_aria_setkey_dec(&ctx, aria_test1_ecb_key, 128 + 64 * i);
8543d3b0591SJens Wiklander         mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_ct[i], blk);
85532b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(
85632b31808SJens Wiklander             memcmp(blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE)
85732b31808SJens Wiklander             != 0);
858*b0563631STom Van Eyck #endif
8593d3b0591SJens Wiklander     }
86032b31808SJens Wiklander     if (verbose) {
8613d3b0591SJens Wiklander         mbedtls_printf("\n");
86232b31808SJens Wiklander     }
8633d3b0591SJens Wiklander 
8643d3b0591SJens Wiklander     /*
8653d3b0591SJens Wiklander      * Test set 2
8663d3b0591SJens Wiklander      */
8673d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CBC)
86832b31808SJens Wiklander     for (i = 0; i < 3; i++) {
8693d3b0591SJens Wiklander         /* Test CBC encryption */
87032b31808SJens Wiklander         if (verbose) {
8713d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CBC-%d (enc): ", 128 + 64 * i);
87232b31808SJens Wiklander         }
8733d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
8743d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
8753d3b0591SJens Wiklander         memset(buf, 0x55, sizeof(buf));
8763d3b0591SJens Wiklander         mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
8773d3b0591SJens Wiklander                                aria_test2_pt, buf);
87832b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cbc_ct[i], 48)
87932b31808SJens Wiklander                               != 0);
8803d3b0591SJens Wiklander 
8813d3b0591SJens Wiklander         /* Test CBC decryption */
88232b31808SJens Wiklander         if (verbose) {
8833d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CBC-%d (dec): ", 128 + 64 * i);
88432b31808SJens Wiklander         }
8853d3b0591SJens Wiklander         mbedtls_aria_setkey_dec(&ctx, aria_test2_key, 128 + 64 * i);
8863d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
8873d3b0591SJens Wiklander         memset(buf, 0xAA, sizeof(buf));
8883d3b0591SJens Wiklander         mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
8893d3b0591SJens Wiklander                                aria_test2_cbc_ct[i], buf);
89032b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
8913d3b0591SJens Wiklander     }
89232b31808SJens Wiklander     if (verbose) {
8933d3b0591SJens Wiklander         mbedtls_printf("\n");
89432b31808SJens Wiklander     }
8953d3b0591SJens Wiklander 
8963d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CBC */
8973d3b0591SJens Wiklander 
8983d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CFB)
89932b31808SJens Wiklander     for (i = 0; i < 3; i++) {
9003d3b0591SJens Wiklander         /* Test CFB encryption */
90132b31808SJens Wiklander         if (verbose) {
9023d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CFB-%d (enc): ", 128 + 64 * i);
90332b31808SJens Wiklander         }
9043d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9053d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
9063d3b0591SJens Wiklander         memset(buf, 0x55, sizeof(buf));
9073d3b0591SJens Wiklander         j = 0;
9083d3b0591SJens Wiklander         mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
9093d3b0591SJens Wiklander                                   aria_test2_pt, buf);
91032b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cfb_ct[i], 48) != 0);
9113d3b0591SJens Wiklander 
9123d3b0591SJens Wiklander         /* Test CFB decryption */
91332b31808SJens Wiklander         if (verbose) {
9143d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CFB-%d (dec): ", 128 + 64 * i);
91532b31808SJens Wiklander         }
9163d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9173d3b0591SJens Wiklander         memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
9183d3b0591SJens Wiklander         memset(buf, 0xAA, sizeof(buf));
9193d3b0591SJens Wiklander         j = 0;
9203d3b0591SJens Wiklander         mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
9213d3b0591SJens Wiklander                                   iv, aria_test2_cfb_ct[i], buf);
92232b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
9233d3b0591SJens Wiklander     }
92432b31808SJens Wiklander     if (verbose) {
9253d3b0591SJens Wiklander         mbedtls_printf("\n");
92632b31808SJens Wiklander     }
9273d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CFB */
9283d3b0591SJens Wiklander 
9293d3b0591SJens Wiklander #if defined(MBEDTLS_CIPHER_MODE_CTR)
93032b31808SJens Wiklander     for (i = 0; i < 3; i++) {
9313d3b0591SJens Wiklander         /* Test CTR encryption */
93232b31808SJens Wiklander         if (verbose) {
9333d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CTR-%d (enc): ", 128 + 64 * i);
93432b31808SJens Wiklander         }
9353d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9363d3b0591SJens Wiklander         memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE);                      // IV = 0
9373d3b0591SJens Wiklander         memset(buf, 0x55, sizeof(buf));
9383d3b0591SJens Wiklander         j = 0;
9393d3b0591SJens Wiklander         mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk,
9403d3b0591SJens Wiklander                                aria_test2_pt, buf);
94132b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_ctr_ct[i], 48) != 0);
9423d3b0591SJens Wiklander 
9433d3b0591SJens Wiklander         /* Test CTR decryption */
94432b31808SJens Wiklander         if (verbose) {
9453d3b0591SJens Wiklander             mbedtls_printf("  ARIA-CTR-%d (dec): ", 128 + 64 * i);
94632b31808SJens Wiklander         }
9473d3b0591SJens Wiklander         mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
9483d3b0591SJens Wiklander         memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE);                      // IV = 0
9493d3b0591SJens Wiklander         memset(buf, 0xAA, sizeof(buf));
9503d3b0591SJens Wiklander         j = 0;
9513d3b0591SJens Wiklander         mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk,
9523d3b0591SJens Wiklander                                aria_test2_ctr_ct[i], buf);
95332b31808SJens Wiklander         ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
9543d3b0591SJens Wiklander     }
95532b31808SJens Wiklander     if (verbose) {
9563d3b0591SJens Wiklander         mbedtls_printf("\n");
95732b31808SJens Wiklander     }
9583d3b0591SJens Wiklander #endif /* MBEDTLS_CIPHER_MODE_CTR */
9593d3b0591SJens Wiklander 
9607901324dSJerome Forissier     ret = 0;
9617901324dSJerome Forissier 
9627901324dSJerome Forissier exit:
9637901324dSJerome Forissier     mbedtls_aria_free(&ctx);
96432b31808SJens Wiklander     return ret;
9653d3b0591SJens Wiklander }
9663d3b0591SJens Wiklander 
9673d3b0591SJens Wiklander #endif /* MBEDTLS_SELF_TEST */
9683d3b0591SJens Wiklander 
9693d3b0591SJens Wiklander #endif /* MBEDTLS_ARIA_C */
970