blob: 41ed7599a07f3af61d06c1dc45b2a994488eeaab [file] [log] [blame]
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +00001/*
2 * ARIA implementation
3 *
4 * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +010022/*
23 * This implementation is based on the following standards:
24 * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf
25 * [2] https://tools.ietf.org/html/rfc5794
26 */
27
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +000028#if !defined(MBEDTLS_CONFIG_FILE)
29#include "mbedtls/config.h"
30#else
31#include MBEDTLS_CONFIG_FILE
32#endif
33
34#if defined(MBEDTLS_ARIA_C)
35
36#include "mbedtls/aria.h"
37
38#include <string.h>
39
40#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
42#include "mbedtls/platform.h"
43#else
44#include <stdio.h>
45#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST */
48
49#if !defined(MBEDTLS_ARIA_ALT)
50
Manuel Pégourié-Gonnard56453932018-02-21 10:08:31 +010051/* Implementation that should never be optimized out by the compiler */
52static void mbedtls_zeroize( void *v, size_t n ) {
53 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
54}
55
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +010056/*
57 * 32-bit integer manipulation macros (little endian)
58 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +000059#ifndef GET_UINT32_LE
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +010060#define GET_UINT32_LE( n, b, i ) \
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +000061{ \
62 (n) = ( (uint32_t) (b)[(i) ] ) \
63 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
64 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
65 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
66}
67#endif
68
69#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +010070#define PUT_UINT32_LE( n, b, i ) \
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +000071{ \
72 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
73 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
74 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
75 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
76}
77#endif
78
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010079/*
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +010080 * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010081 *
82 * This is submatrix P1 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +010083 *
84 * Common compilers fail to translate this to minimal number of instructions,
85 * so let's provide asm versions for common platforms with C fallback.
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010086 */
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +010087#if defined(MBEDTLS_HAVE_ASM)
88#if defined(__arm__)
89/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
90#if defined(__GNUC__) && \
91 ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
92static inline uint32_t aria_p1( uint32_t x )
93{
94 uint32_t r;
95 asm( "rev16 %0, %1" : "=l" (r) : "l" (x) );
96 return( r );
97}
98#define ARIA_P1 aria_p1
99#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000
100static __inline uint32_t aria_p1( uint32_t x )
101{
102 uint32_t r;
103 __asm( "rev16 r, x" );
104 return( r );
105}
106#define ARIA_P1 aria_p1
107#endif
108#endif /* arm */
109#if defined(__GNUC__) && \
110 defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100111/* I couldn't find an Intel equivalent of ret16, so two instructions */
112#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) )
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +0100113#endif /* x86 gnuc */
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100114#endif /* MBEDTLS_HAVE_ASM && GNUC */
115#if !defined(ARIA_P1)
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100116#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100117#endif
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000118
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100119/*
120 * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
121 *
122 * This is submatrix P2 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100123 *
124 * Common compilers will translate this to a single instruction.
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100125 */
126#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000127
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100128/*
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100129 * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
130 *
131 * This is submatrix P3 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100132 *
133 * Some compilers fail to translate this to a single instruction,
134 * so let's provide asm versions for common platforms with C fallback.
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100135 */
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +0100136#if defined(MBEDTLS_HAVE_ASM)
137#if defined(__arm__)
138/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
139#if defined(__GNUC__) && \
140 ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
141static inline uint32_t aria_p3( uint32_t x )
142{
143 uint32_t r;
144 asm( "rev %0, %1" : "=l" (r) : "l" (x) );
145 return( r );
146}
147#define ARIA_P3 aria_p3
148#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000
149static __inline uint32_t aria_p3( uint32_t x )
150{
151 uint32_t r;
152 __asm( "rev r, x" );
153 return( r );
154}
155#define ARIA_P3 aria_p3
156#endif
157#endif /* arm */
158#if defined(__GNUC__) && \
159 defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100160static inline uint32_t aria_p3( uint32_t x )
161{
162 asm( "bswap %0" : "=r" (x) : "0" (x) );
163 return( x );
164}
165#define ARIA_P3 aria_p3
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +0100166#endif /* x86 gnuc */
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100167#endif /* MBEDTLS_HAVE_ASM && GNUC */
168#if !defined(ARIA_P3)
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100169#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) )
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100170#endif
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100171
172/*
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100173 * ARIA Affine Transform
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +0100174 * (a, b, c, d) = state in/out
175 *
176 * If we denote the first by of input by 0, ..., the last byte by f,
177 * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
178 *
179 * Reading [1] 2.4 or [2] 2.4.3 in colums and performing simple
180 * rearrangements on adjacent pairs, output is:
181 *
182 * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
183 * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
184 * b = 0101 + 2323 + 5476 + 8998 + baab + ecec + ffdd
185 * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
186 * c = 0022 + 1133 + 4545 + 7667 + ab89 + dcdc + fefe
187 * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
188 * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cedf
189 * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
190 *
191 * Note: another presentation of the A transform can be found as the first
192 * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
193 * The implementation below uses only P1 and P2 as they are sufficient.
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100194 */
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100195static inline void aria_a( uint32_t *a, uint32_t *b,
196 uint32_t *c, uint32_t *d )
197{
198 uint32_t ta, tb, tc;
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +0100199 ta = *b; // 4567
200 *b = *a; // 0123
201 *a = ARIA_P2( ta ); // 6745
202 tb = ARIA_P2( *d ); // efcd
203 *d = ARIA_P1( *c ); // 98ba
204 *c = ARIA_P1( tb ); // fedc
205 ta ^= *d; // 4567+98ba
206 tc = ARIA_P2( *b ); // 2301
207 ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc
208 tb ^= ARIA_P2( *d ); // ba98+efcd
209 tc ^= ARIA_P1( *a ); // 2301+7654
210 *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
211 tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc
212 *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
213 ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe
214 *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT
215 tc = ARIA_P2( tc ); // 0123+5476
216 *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000217}
218
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100219/*
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100220 * ARIA Substitution Layer SL1 / SL2
221 * (a, b, c, d) = state in/out
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100222 * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100223 *
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100224 * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
225 * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100226 */
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100227static inline void aria_sl( uint32_t *a, uint32_t *b,
228 uint32_t *c, uint32_t *d,
229 const uint8_t sa[0x100], const uint8_t sb[0x100],
230 const uint8_t sc[0x100], const uint8_t sd[0x100] )
Manuel Pégourié-Gonnard8c76a942018-02-21 12:03:22 +0100231{
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100232 *a = ( (uint32_t) sa[ *a & 0xFF]) ^
233 (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^
234 (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
235 (((uint32_t) sd[ *a >> 24 ]) << 24);
236 *b = ( (uint32_t) sa[ *b & 0xFF]) ^
237 (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^
238 (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
239 (((uint32_t) sd[ *b >> 24 ]) << 24);
240 *c = ( (uint32_t) sa[ *c & 0xFF]) ^
241 (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^
242 (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
243 (((uint32_t) sd[ *c >> 24 ]) << 24);
244 *d = ( (uint32_t) sa[ *d & 0xFF]) ^
245 (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^
246 (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
247 (((uint32_t) sd[ *d >> 24 ]) << 24);
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000248}
249
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100250/*
251 * S-Boxes
252 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000253static const uint8_t aria_sb1[0x100] =
254{
255 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
256 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
257 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
258 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
259 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
260 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
261 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
262 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
263 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
264 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
265 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
266 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
267 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
268 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
269 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
270 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
271 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
272 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
273 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
274 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
275 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
276 0xB0, 0x54, 0xBB, 0x16
277};
278
279static const uint8_t aria_sb2[0x100] =
280{
281 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
282 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
283 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
284 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
285 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
286 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
287 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
288 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
289 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
290 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
291 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
292 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
293 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
294 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
295 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
296 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
297 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
298 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
299 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
300 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
301 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
302 0xAF, 0xBA, 0xB5, 0x81
303};
304
305static const uint8_t aria_is1[0x100] =
306{
307 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
308 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
309 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
310 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
311 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
312 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
313 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
314 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
315 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
316 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
317 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
318 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
319 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
320 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
321 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
322 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
323 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
324 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
325 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
326 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
327 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
328 0x55, 0x21, 0x0C, 0x7D
329};
330
331static const uint8_t aria_is2[0x100] =
332{
333 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
334 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
335 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
336 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
337 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
338 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
339 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
340 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
341 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
342 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
343 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
344 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
345 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
346 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
347 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
348 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
349 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
350 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
351 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
352 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
353 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
354 0x03, 0xA2, 0xAC, 0x60
355};
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000356
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100357/*
358 * Helper for key schedule: r = FO( p, k ) ^ x
359 */
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100360static void aria_fo_xor( uint32_t r[4],
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000361 const uint32_t p[4], const uint32_t k[4], const uint32_t x[4] )
362{
363 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000364
365 a = p[0] ^ k[0];
366 b = p[1] ^ k[1];
367 c = p[2] ^ k[2];
368 d = p[3] ^ k[3];
369
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100370 aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
371 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000372
373 r[0] = a ^ x[0];
374 r[1] = b ^ x[1];
375 r[2] = c ^ x[2];
376 r[3] = d ^ x[3];
377}
378
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100379/*
380 * Helper for key schedule: r = FE( p, k ) ^ x
381 */
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100382static void aria_fe_xor(uint32_t r[4],
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000383 const uint32_t p[4], const uint32_t k[4], const uint32_t x[4] )
384{
385 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000386
387 a = p[0] ^ k[0];
388 b = p[1] ^ k[1];
389 c = p[2] ^ k[2];
390 d = p[3] ^ k[3];
391
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100392 aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
393 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000394
395 r[0] = a ^ x[0];
396 r[1] = b ^ x[1];
397 r[2] = c ^ x[2];
398 r[3] = d ^ x[3];
399}
400
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100401/*
402 * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
403 *
404 * We chose to store bytes into 32-bit words in little-endian format (see
405 * GET/PUT_UINT32_LE) so we need to reverse bytes here.
406 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000407static void aria_rot128(uint32_t r[4], const uint32_t a[4],
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100408 const uint32_t b[4], uint8_t n)
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000409{
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100410 uint8_t i, j;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000411 uint32_t t, u;
412
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100413 const uint8_t n1 = n % 32; // bit offset
414 const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100415
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100416 j = (n / 32) % 4; // initial word offset
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100417 t = ARIA_P3( b[j] ); // big endian
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000418 for( i = 0; i < 4; i++ )
419 {
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100420 j = (j + 1) % 4; // get next word, big endian
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100421 u = ARIA_P3( b[j] );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000422 t <<= n1; // rotate
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100423 t |= u >> n2;
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100424 t = ARIA_P3( t ); // back to little endian
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000425 r[i] = a[i] ^ t; // store
426 t = u; // move to next word
427 }
428}
429
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100430/*
431 * Set encryption key
432 */
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100433int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
434 const unsigned char *key, unsigned int keybits )
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000435{
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100436 /* round constant masks */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000437 const uint32_t rc[3][4] =
438 {
439 { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA },
440 { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF },
441 { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 }
442 };
443
444 int i;
445 uint32_t w[4][4], *w2;
446
447 if (keybits != 128 && keybits != 192 && keybits != 256)
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100448 return( MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000449
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100450 /* Copy key to W0 (and potential remainder to W1) */
451 GET_UINT32_LE( w[0][0], key, 0 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000452 GET_UINT32_LE( w[0][1], key, 4 );
453 GET_UINT32_LE( w[0][2], key, 8 );
454 GET_UINT32_LE( w[0][3], key, 12 );
455
456 memset(w[1], 0, 16);
457 if( keybits >= 192 )
458 {
459 GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key
460 GET_UINT32_LE( w[1][1], key, 20 );
461 }
462 if( keybits == 256 )
463 {
464 GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key
465 GET_UINT32_LE( w[1][3], key, 28 );
466 }
467
468 i = (keybits - 128) >> 6; // index: 0, 1, 2
469 ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16
470
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100471 aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000472 i = i < 2 ? i + 1 : 0;
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100473 aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000474 i = i < 2 ? i + 1 : 0;
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100475 aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000476
477 for( i = 0; i < 4; i++ ) // create round keys
478 {
479 w2 = w[(i + 1) & 3];
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100480 aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 );
481 aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 );
482 aria_rot128( ctx->rk[i + 8], w[i], w2, 61 );
483 aria_rot128( ctx->rk[i + 12], w[i], w2, 31 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000484 }
485 aria_rot128( ctx->rk[16], w[0], w[1], 19 );
486
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100487 return( 0 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000488}
489
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100490/*
491 * Set decryption key
492 */
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100493int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
494 const unsigned char *key, unsigned int keybits )
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000495{
496 int i, j, k, ret;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000497
498 ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
499 if( ret != 0 )
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100500 return( ret );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000501
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100502 /* flip the order of round keys */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000503 for( i = 0, j = ctx->nr; i < j; i++, j-- )
504 {
505 for( k = 0; k < 4; k++ )
506 {
Manuel Pégourié-Gonnarde1ad7492018-02-20 13:59:05 +0100507 uint32_t t = ctx->rk[i][k];
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000508 ctx->rk[i][k] = ctx->rk[j][k];
509 ctx->rk[j][k] = t;
510 }
511 }
512
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100513 /* apply affine transform to middle keys */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000514 for (i = 1; i < ctx->nr; i++ )
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100515 {
516 aria_a( &ctx->rk[i][0], &ctx->rk[i][1],
517 &ctx->rk[i][2], &ctx->rk[i][3] );
518 }
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000519
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100520 return( 0 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000521}
522
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100523/*
524 * Encrypt a block
525 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000526int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
527 int mode,
528 const unsigned char input[16],
529 unsigned char output[16] )
530{
531 int i;
532
533 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000534
535 ( (void) mode );
536
537 GET_UINT32_LE( a, input, 0 );
538 GET_UINT32_LE( b, input, 4 );
539 GET_UINT32_LE( c, input, 8 );
540 GET_UINT32_LE( d, input, 12 );
541
542 i = 0;
543 while (1)
544 {
545 a ^= ctx->rk[i][0];
546 b ^= ctx->rk[i][1];
547 c ^= ctx->rk[i][2];
548 d ^= ctx->rk[i][3];
549 i++;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100550
551 aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
552 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000553
554 a ^= ctx->rk[i][0];
555 b ^= ctx->rk[i][1];
556 c ^= ctx->rk[i][2];
557 d ^= ctx->rk[i][3];
558 i++;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100559
560 aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000561 if (i >= ctx->nr)
562 break;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100563 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000564 }
565
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100566 /* final key mixing */
567 a ^= ctx->rk[i][0];
568 b ^= ctx->rk[i][1];
569 c ^= ctx->rk[i][2];
570 d ^= ctx->rk[i][3];
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000571
572 PUT_UINT32_LE( a, output, 0 );
573 PUT_UINT32_LE( b, output, 4 );
574 PUT_UINT32_LE( c, output, 8 );
575 PUT_UINT32_LE( d, output, 12 );
576
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100577 return( 0 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000578}
579
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100580/* Initialize context */
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000581void mbedtls_aria_init( mbedtls_aria_context *ctx )
582{
583 memset( ctx, 0, sizeof( mbedtls_aria_context ) );
584}
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000585
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100586/* Clear context */
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000587void mbedtls_aria_free( mbedtls_aria_context *ctx )
588{
589 if( ctx == NULL )
590 return;
591
Manuel Pégourié-Gonnard56453932018-02-21 10:08:31 +0100592 mbedtls_zeroize( ctx, sizeof( mbedtls_aria_context ) );
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000593}
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000594
595#if defined(MBEDTLS_CIPHER_MODE_CBC)
596/*
597 * ARIA-CBC buffer encryption/decryption
598 */
599int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100600 int mode,
601 size_t length,
602 unsigned char iv[16],
603 const unsigned char *input,
604 unsigned char *output )
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000605{
606 int i;
607 unsigned char temp[16];
608
609 if( length % 16 )
610 return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
611
612 if( mode == MBEDTLS_ARIA_DECRYPT )
613 {
614 while( length > 0 )
615 {
616 memcpy( temp, input, 16 );
617 mbedtls_aria_crypt_ecb( ctx, mode, input, output );
618
619 for( i = 0; i < 16; i++ )
620 output[i] = (unsigned char)( output[i] ^ iv[i] );
621
622 memcpy( iv, temp, 16 );
623
624 input += 16;
625 output += 16;
626 length -= 16;
627 }
628 }
629 else
630 {
631 while( length > 0 )
632 {
633 for( i = 0; i < 16; i++ )
634 output[i] = (unsigned char)( input[i] ^ iv[i] );
635
636 mbedtls_aria_crypt_ecb( ctx, mode, output, output );
637 memcpy( iv, output, 16 );
638
639 input += 16;
640 output += 16;
641 length -= 16;
642 }
643 }
644
645 return( 0 );
646}
647#endif /* MBEDTLS_CIPHER_MODE_CBC */
648
649#if defined(MBEDTLS_CIPHER_MODE_CFB)
650/*
651 * ARIA-CFB128 buffer encryption/decryption
652 */
653int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100654 int mode,
655 size_t length,
656 size_t *iv_off,
657 unsigned char iv[16],
658 const unsigned char *input,
659 unsigned char *output )
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000660{
661 int c;
662 size_t n = *iv_off;
663
664 if( mode == MBEDTLS_ARIA_DECRYPT )
665 {
666 while( length-- )
667 {
668 if( n == 0 )
669 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, iv, iv );
670
671 c = *input++;
672 *output++ = (unsigned char)( c ^ iv[n] );
673 iv[n] = (unsigned char) c;
674
675 n = ( n + 1 ) & 0x0F;
676 }
677 }
678 else
679 {
680 while( length-- )
681 {
682 if( n == 0 )
683 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, iv, iv );
684
685 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
686
687 n = ( n + 1 ) & 0x0F;
688 }
689 }
690
691 *iv_off = n;
692
693 return( 0 );
694}
695#endif /* MBEDTLS_CIPHER_MODE_CFB */
696
697#if defined(MBEDTLS_CIPHER_MODE_CTR)
698/*
699 * ARIA-CTR buffer encryption/decryption
700 */
701int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
Manuel Pégourié-Gonnard4231e7f2018-02-28 10:54:31 +0100702 size_t length,
703 size_t *nc_off,
704 unsigned char nonce_counter[16],
705 unsigned char stream_block[16],
706 const unsigned char *input,
707 unsigned char *output )
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000708{
709 int c, i;
710 size_t n = *nc_off;
711
712 while( length-- )
713 {
714 if( n == 0 ) {
715 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, nonce_counter,
716 stream_block );
717
718 for( i = 16; i > 0; i-- )
719 if( ++nonce_counter[i - 1] != 0 )
720 break;
721 }
722 c = *input++;
723 *output++ = (unsigned char)( c ^ stream_block[n] );
724
725 n = ( n + 1 ) & 0x0F;
726 }
727
728 *nc_off = n;
729
730 return( 0 );
731}
732#endif /* MBEDTLS_CIPHER_MODE_CTR */
733#endif /* !MBEDTLS_ARIA_ALT */
734
735#if defined(MBEDTLS_SELF_TEST)
736
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100737/*
738 * Basic ARIA ECB test vectors from RFC 5794
739 */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000740static const uint8_t aria_test1_ecb_key[32] = // test key
741{
742 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit
743 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
744 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit
745 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit
746};
747
748static const uint8_t aria_test1_ecb_pt[16] = // plaintext
749{
750 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all
751 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes
752};
753
754static const uint8_t aria_test1_ecb_ct[3][16] = // ciphertext
755{
756 { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit
757 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
758 { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit
759 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
760 { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit
761 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
762};
763
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100764/*
765 * Mode tests from "Test Vectors for ARIA" Version 1.0
766 * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
767 */
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000768#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000769 defined(MBEDTLS_CIPHER_MODE_CTR))
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000770static const uint8_t aria_test2_key[32] =
771{
772 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit
773 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
774 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit
775 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit
776};
777
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000778static const uint8_t aria_test2_pt[48] =
779{
780 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all
781 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
782 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
783 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
784 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
785 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
786};
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000787#endif
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000788
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000789#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
790static const uint8_t aria_test2_iv[16] =
791{
792 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB
793 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV
794};
795#endif
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000796
797#if defined(MBEDTLS_CIPHER_MODE_CBC)
798static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertxt
799{
800 { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key
801 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
802 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
803 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
804 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
805 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
806 { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key
807 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
808 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
809 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
810 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
811 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
812 { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key
813 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
814 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
815 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
816 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
817 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
818};
819#endif /* MBEDTLS_CIPHER_MODE_CBC */
820
821#if defined(MBEDTLS_CIPHER_MODE_CFB)
822static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertxt
823{
824 { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key
825 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
826 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
827 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
828 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
829 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
830 { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key
831 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
832 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
833 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
834 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
835 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
836 { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key
837 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
838 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
839 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
840 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
841 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
842};
843#endif /* MBEDTLS_CIPHER_MODE_CFB */
844
845#if defined(MBEDTLS_CIPHER_MODE_CTR)
846static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertxt
847{
848 { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key
849 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
850 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
851 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
852 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
853 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
854 { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key
855 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
856 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
857 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
858 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
859 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
860 { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key
861 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
862 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
863 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
864 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
865 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
866};
867#endif /* MBEDTLS_CIPHER_MODE_CFB */
868
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000869#define ARIA_SELF_TEST_IF_FAIL \
870 { \
871 if( verbose ) \
872 printf( "failed\n" ); \
873 return( 1 ); \
874 } else { \
875 if( verbose ) \
876 printf( "passed\n" ); \
877 }
878
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100879/*
880 * Checkup routine
881 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000882int mbedtls_aria_self_test( int verbose )
883{
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000884 int i;
885 uint8_t blk[16];
886 mbedtls_aria_context ctx;
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000887
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000888#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
889 size_t j;
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000890#endif
891
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000892#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
893 defined(MBEDTLS_CIPHER_MODE_CFB) || \
894 defined(MBEDTLS_CIPHER_MODE_CTR))
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000895 uint8_t buf[48], iv[16];
896#endif
897
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100898 /*
899 * Test set 1
900 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000901 for( i = 0; i < 3; i++ )
902 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100903 /* test ECB encryption */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000904 if( verbose )
905 printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i);
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000906 mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000907 mbedtls_aria_crypt_ecb( &ctx, MBEDTLS_ARIA_ENCRYPT,
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000908 aria_test1_ecb_pt, blk );
909 if( memcmp( blk, aria_test1_ecb_ct[i], 16 ) != 0 )
910 ARIA_SELF_TEST_IF_FAIL;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000911
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100912 /* test ECB decryption */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000913 if( verbose )
914 printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i);
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000915 mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000916 mbedtls_aria_crypt_ecb( &ctx, MBEDTLS_ARIA_DECRYPT,
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000917 aria_test1_ecb_ct[i], blk );
918 if (memcmp( blk, aria_test1_ecb_pt, 16 ) != 0)
919 ARIA_SELF_TEST_IF_FAIL;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000920 }
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000921 if( verbose )
922 printf("\n");
923
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100924 /*
925 * Test set 2
926 */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000927#if defined(MBEDTLS_CIPHER_MODE_CBC)
928 for( i = 0; i < 3; i++ )
929 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100930 /* Test CBC encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000931 if( verbose )
932 printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i);
933 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
934 memcpy( iv, aria_test2_iv, 16 );
935 memset( buf, 0x55, sizeof(buf) );
936 mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
937 aria_test2_pt, buf );
938 if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
939 ARIA_SELF_TEST_IF_FAIL;
940
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100941 /* Test CBC decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000942 if( verbose )
943 printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i);
944 mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i );
945 memcpy( iv, aria_test2_iv, 16 );
946 memset( buf, 0xAA, sizeof(buf) );
947 mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
948 aria_test2_cbc_ct[i], buf );
949 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
950 ARIA_SELF_TEST_IF_FAIL;
951 }
952 if( verbose )
953 printf("\n");
954
955#endif /* MBEDTLS_CIPHER_MODE_CBC */
956
957#if defined(MBEDTLS_CIPHER_MODE_CFB)
958 for( i = 0; i < 3; i++ )
959 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100960 /* Test CFB encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000961 if( verbose )
962 printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i);
963 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
964 memcpy( iv, aria_test2_iv, 16 );
965 memset( buf, 0x55, sizeof(buf) );
966 j = 0;
967 mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
968 aria_test2_pt, buf );
969 if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
970 ARIA_SELF_TEST_IF_FAIL;
971
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100972 /* Test CFB decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000973 if( verbose )
974 printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i);
975 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
976 memcpy( iv, aria_test2_iv, 16 );
977 memset( buf, 0xAA, sizeof(buf) );
978 j = 0;
979 mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
980 iv, aria_test2_cfb_ct[i], buf );
981 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
982 ARIA_SELF_TEST_IF_FAIL;
983 }
984 if( verbose )
985 printf("\n");
986#endif /* MBEDTLS_CIPHER_MODE_CFB */
987
988#if defined(MBEDTLS_CIPHER_MODE_CTR)
989 for( i = 0; i < 3; i++ )
990 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100991 /* Test CTR encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000992 if( verbose )
993 printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i);
994 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
995 memset( iv, 0, 16 ); // IV = 0
996 memset( buf, 0x55, sizeof(buf) );
997 j = 0;
998 mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
999 aria_test2_pt, buf );
1000 if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
1001 ARIA_SELF_TEST_IF_FAIL;
1002
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +01001003 /* Test CTR decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +00001004 if( verbose )
1005 printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i);
1006 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
1007 memset( iv, 0, 16 ); // IV = 0
1008 memset( buf, 0xAA, sizeof(buf) );
1009 j = 0;
1010 mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
1011 aria_test2_ctr_ct[i], buf );
1012 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
1013 ARIA_SELF_TEST_IF_FAIL;
1014 }
1015 if( verbose )
1016 printf("\n");
1017#endif /* MBEDTLS_CIPHER_MODE_CTR */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +00001018
1019 return( 0 );
1020}
1021
1022#endif /* MBEDTLS_SELF_TEST */
1023
1024#endif /* MBEDTLS_ARIA_C */