1/*
2 * ARIA implementation
3 *
4 * Copyright The Mbed TLS Contributors
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
20/*
21 * This implementation is based on the following standards:
22 * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf
23 * [2] https://tools.ietf.org/html/rfc5794
24 */
25
26#include "common.h"
27
28#if defined(MBEDTLS_ARIA_C)
29
30#include "mbedtls/aria.h"
31
32#include <string.h>
33
34#include "mbedtls/platform.h"
35
36#if !defined(MBEDTLS_ARIA_ALT)
37
38#include "mbedtls/platform_util.h"
39
40/* Parameter validation macros */
41#define ARIA_VALIDATE_RET(cond) \
42 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA)
43#define ARIA_VALIDATE(cond) \
44 MBEDTLS_INTERNAL_VALIDATE(cond)
45
46/*
47 * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
48 *
49 * This is submatrix P1 in [1] Appendix B.1
50 *
51 * Common compilers fail to translate this to minimal number of instructions,
52 * so let's provide asm versions for common platforms with C fallback.
53 */
54#if defined(MBEDTLS_HAVE_ASM)
55#if defined(__arm__) /* rev16 available from v6 up */
56/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
57#if defined(__GNUC__) && \
58 (!defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000) && \
59 __ARM_ARCH >= 6
60static inline uint32_t aria_p1(uint32_t x)
61{
62 uint32_t r;
63 __asm("rev16 %0, %1" : "=l" (r) : "l" (x));
64 return r;
65}
66#define ARIA_P1 aria_p1
67#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
68 (__TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3)
69static inline uint32_t aria_p1(uint32_t x)
70{
71 uint32_t r;
72 __asm("rev16 r, x");
73 return r;
74}
75#define ARIA_P1 aria_p1
76#endif
77#endif /* arm */
78#if defined(__GNUC__) && \
79 defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
80/* I couldn't find an Intel equivalent of rev16, so two instructions */
81#define ARIA_P1(x) ARIA_P2(ARIA_P3(x))
82#endif /* x86 gnuc */
83#endif /* MBEDTLS_HAVE_ASM && GNUC */
84#if !defined(ARIA_P1)
85#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
86#endif
87
88/*
89 * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
90 *
91 * This is submatrix P2 in [1] Appendix B.1
92 *
93 * Common compilers will translate this to a single instruction.
94 */
95#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
96
97/*
98 * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
99 *
100 * This is submatrix P3 in [1] Appendix B.1
101 *
102 * Some compilers fail to translate this to a single instruction,
103 * so let's provide asm versions for common platforms with C fallback.
104 */
105#if defined(MBEDTLS_HAVE_ASM)
106#if defined(__arm__) /* rev available from v6 up */
107/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
108#if defined(__GNUC__) && \
109 (!defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000) && \
110 __ARM_ARCH >= 6
111static inline uint32_t aria_p3(uint32_t x)
112{
113 uint32_t r;
114 __asm("rev %0, %1" : "=l" (r) : "l" (x));
115 return r;
116}
117#define ARIA_P3 aria_p3
118#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
119 (__TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3)
120static inline uint32_t aria_p3(uint32_t x)
121{
122 uint32_t r;
123 __asm("rev r, x");
124 return r;
125}
126#define ARIA_P3 aria_p3
127#endif
128#endif /* arm */
129#if defined(__GNUC__) && \
130 defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
131static inline uint32_t aria_p3(uint32_t x)
132{
133 __asm("bswap %0" : "=r" (x) : "0" (x));
134 return x;
135}
136#define ARIA_P3 aria_p3
137#endif /* x86 gnuc */
138#endif /* MBEDTLS_HAVE_ASM && GNUC */
139#if !defined(ARIA_P3)
140#define ARIA_P3(x) ARIA_P2(ARIA_P1(x))
141#endif
142
143/*
144 * ARIA Affine Transform
145 * (a, b, c, d) = state in/out
146 *
147 * If we denote the first byte of input by 0, ..., the last byte by f,
148 * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
149 *
150 * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple
151 * rearrangements on adjacent pairs, output is:
152 *
153 * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
154 * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
155 * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd
156 * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
157 * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe
158 * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
159 * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef
160 * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
161 *
162 * Note: another presentation of the A transform can be found as the first
163 * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
164 * The implementation below uses only P1 and P2 as they are sufficient.
165 */
166static inline void aria_a(uint32_t *a, uint32_t *b,
167 uint32_t *c, uint32_t *d)
168{
169 uint32_t ta, tb, tc;
170 ta = *b; // 4567
171 *b = *a; // 0123
172 *a = ARIA_P2(ta); // 6745
173 tb = ARIA_P2(*d); // efcd
174 *d = ARIA_P1(*c); // 98ba
175 *c = ARIA_P1(tb); // fedc
176 ta ^= *d; // 4567+98ba
177 tc = ARIA_P2(*b); // 2301
178 ta = ARIA_P1(ta) ^ tc ^ *c; // 2301+5476+89ab+fedc
179 tb ^= ARIA_P2(*d); // ba98+efcd
180 tc ^= ARIA_P1(*a); // 2301+7654
181 *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
182 tb = ARIA_P2(tb) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc
183 *a ^= ARIA_P1(tb); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
184 ta = ARIA_P2(ta); // 0123+7654+ab89+dcfe
185 *d ^= ARIA_P1(ta) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT
186 tc = ARIA_P2(tc); // 0123+5476
187 *c ^= ARIA_P1(tc) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
188}
189
190/*
191 * ARIA Substitution Layer SL1 / SL2
192 * (a, b, c, d) = state in/out
193 * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
194 *
195 * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
196 * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
197 */
198static inline void aria_sl(uint32_t *a, uint32_t *b,
199 uint32_t *c, uint32_t *d,
200 const uint8_t sa[256], const uint8_t sb[256],
201 const uint8_t sc[256], const uint8_t sd[256])
202{
203 *a = ((uint32_t) sa[MBEDTLS_BYTE_0(*a)]) ^
204 (((uint32_t) sb[MBEDTLS_BYTE_1(*a)]) << 8) ^
205 (((uint32_t) sc[MBEDTLS_BYTE_2(*a)]) << 16) ^
206 (((uint32_t) sd[MBEDTLS_BYTE_3(*a)]) << 24);
207 *b = ((uint32_t) sa[MBEDTLS_BYTE_0(*b)]) ^
208 (((uint32_t) sb[MBEDTLS_BYTE_1(*b)]) << 8) ^
209 (((uint32_t) sc[MBEDTLS_BYTE_2(*b)]) << 16) ^
210 (((uint32_t) sd[MBEDTLS_BYTE_3(*b)]) << 24);
211 *c = ((uint32_t) sa[MBEDTLS_BYTE_0(*c)]) ^
212 (((uint32_t) sb[MBEDTLS_BYTE_1(*c)]) << 8) ^
213 (((uint32_t) sc[MBEDTLS_BYTE_2(*c)]) << 16) ^
214 (((uint32_t) sd[MBEDTLS_BYTE_3(*c)]) << 24);
215 *d = ((uint32_t) sa[MBEDTLS_BYTE_0(*d)]) ^
216 (((uint32_t) sb[MBEDTLS_BYTE_1(*d)]) << 8) ^
217 (((uint32_t) sc[MBEDTLS_BYTE_2(*d)]) << 16) ^
218 (((uint32_t) sd[MBEDTLS_BYTE_3(*d)]) << 24);
219}
220
221/*
222 * S-Boxes
223 */
224static const uint8_t aria_sb1[256] =
225{
226 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
227 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
228 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
229 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
230 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
231 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
232 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
233 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
234 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
235 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
236 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
237 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
238 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
239 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
240 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
241 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
242 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
243 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
244 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
245 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
246 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
247 0xB0, 0x54, 0xBB, 0x16
248};
249
250static const uint8_t aria_sb2[256] =
251{
252 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
253 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
254 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
255 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
256 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
257 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
258 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
259 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
260 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
261 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
262 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
263 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
264 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
265 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
266 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
267 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
268 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
269 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
270 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
271 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
272 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
273 0xAF, 0xBA, 0xB5, 0x81
274};
275
276static const uint8_t aria_is1[256] =
277{
278 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
279 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
280 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
281 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
282 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
283 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
284 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
285 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
286 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
287 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
288 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
289 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
290 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
291 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
292 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
293 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
294 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
295 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
296 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
297 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
298 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
299 0x55, 0x21, 0x0C, 0x7D
300};
301
302static const uint8_t aria_is2[256] =
303{
304 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
305 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
306 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
307 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
308 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
309 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
310 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
311 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
312 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
313 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
314 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
315 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
316 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
317 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
318 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
319 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
320 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
321 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
322 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
323 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
324 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
325 0x03, 0xA2, 0xAC, 0x60
326};
327
328/*
329 * Helper for key schedule: r = FO( p, k ) ^ x
330 */
331static void aria_fo_xor(uint32_t r[4], const uint32_t p[4],
332 const uint32_t k[4], const uint32_t x[4])
333{
334 uint32_t a, b, c, d;
335
336 a = p[0] ^ k[0];
337 b = p[1] ^ k[1];
338 c = p[2] ^ k[2];
339 d = p[3] ^ k[3];
340
341 aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2);
342 aria_a(&a, &b, &c, &d);
343
344 r[0] = a ^ x[0];
345 r[1] = b ^ x[1];
346 r[2] = c ^ x[2];
347 r[3] = d ^ x[3];
348}
349
350/*
351 * Helper for key schedule: r = FE( p, k ) ^ x
352 */
353static void aria_fe_xor(uint32_t r[4], const uint32_t p[4],
354 const uint32_t k[4], const uint32_t x[4])
355{
356 uint32_t a, b, c, d;
357
358 a = p[0] ^ k[0];
359 b = p[1] ^ k[1];
360 c = p[2] ^ k[2];
361 d = p[3] ^ k[3];
362
363 aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2);
364 aria_a(&a, &b, &c, &d);
365
366 r[0] = a ^ x[0];
367 r[1] = b ^ x[1];
368 r[2] = c ^ x[2];
369 r[3] = d ^ x[3];
370}
371
372/*
373 * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
374 *
375 * We chose to store bytes into 32-bit words in little-endian format (see
376 * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse
377 * bytes here.
378 */
379static void aria_rot128(uint32_t r[4], const uint32_t a[4],
380 const uint32_t b[4], uint8_t n)
381{
382 uint8_t i, j;
383 uint32_t t, u;
384
385 const uint8_t n1 = n % 32; // bit offset
386 const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset
387
388 j = (n / 32) % 4; // initial word offset
389 t = ARIA_P3(b[j]); // big endian
390 for (i = 0; i < 4; i++) {
391 j = (j + 1) % 4; // get next word, big endian
392 u = ARIA_P3(b[j]);
393 t <<= n1; // rotate
394 t |= u >> n2;
395 t = ARIA_P3(t); // back to little endian
396 r[i] = a[i] ^ t; // store
397 t = u; // move to next word
398 }
399}
400
401/*
402 * Set encryption key
403 */
404int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
405 const unsigned char *key, unsigned int keybits)
406{
407 /* round constant masks */
408 const uint32_t rc[3][4] =
409 {
410 { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA },
411 { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF },
412 { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 }
413 };
414
415 int i;
416 uint32_t w[4][4], *w2;
417 ARIA_VALIDATE_RET(ctx != NULL);
418 ARIA_VALIDATE_RET(key != NULL);
419
420 if (keybits != 128 && keybits != 192 && keybits != 256) {
421 return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
422 }
423
424 /* Copy key to W0 (and potential remainder to W1) */
425 w[0][0] = MBEDTLS_GET_UINT32_LE(key, 0);
426 w[0][1] = MBEDTLS_GET_UINT32_LE(key, 4);
427 w[0][2] = MBEDTLS_GET_UINT32_LE(key, 8);
428 w[0][3] = MBEDTLS_GET_UINT32_LE(key, 12);
429
430 memset(w[1], 0, 16);
431 if (keybits >= 192) {
432 w[1][0] = MBEDTLS_GET_UINT32_LE(key, 16); // 192 bit key
433 w[1][1] = MBEDTLS_GET_UINT32_LE(key, 20);
434 }
435 if (keybits == 256) {
436 w[1][2] = MBEDTLS_GET_UINT32_LE(key, 24); // 256 bit key
437 w[1][3] = MBEDTLS_GET_UINT32_LE(key, 28);
438 }
439
440 i = (keybits - 128) >> 6; // index: 0, 1, 2
441 ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16
442
443 aria_fo_xor(w[1], w[0], rc[i], w[1]); // W1 = FO(W0, CK1) ^ KR
444 i = i < 2 ? i + 1 : 0;
445 aria_fe_xor(w[2], w[1], rc[i], w[0]); // W2 = FE(W1, CK2) ^ W0
446 i = i < 2 ? i + 1 : 0;
447 aria_fo_xor(w[3], w[2], rc[i], w[1]); // W3 = FO(W2, CK3) ^ W1
448
449 for (i = 0; i < 4; i++) { // create round keys
450 w2 = w[(i + 1) & 3];
451 aria_rot128(ctx->rk[i], w[i], w2, 128 - 19);
452 aria_rot128(ctx->rk[i + 4], w[i], w2, 128 - 31);
453 aria_rot128(ctx->rk[i + 8], w[i], w2, 61);
454 aria_rot128(ctx->rk[i + 12], w[i], w2, 31);
455 }
456 aria_rot128(ctx->rk[16], w[0], w[1], 19);
457
458 /* w holds enough info to reconstruct the round keys */
459 mbedtls_platform_zeroize(w, sizeof(w));
460
461 return 0;
462}
463
464/*
465 * Set decryption key
466 */
467int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
468 const unsigned char *key, unsigned int keybits)
469{
470 int i, j, k, ret;
471 ARIA_VALIDATE_RET(ctx != NULL);
472 ARIA_VALIDATE_RET(key != NULL);
473
474 ret = mbedtls_aria_setkey_enc(ctx, key, keybits);
475 if (ret != 0) {
476 return ret;
477 }
478
479 /* flip the order of round keys */
480 for (i = 0, j = ctx->nr; i < j; i++, j--) {
481 for (k = 0; k < 4; k++) {
482 uint32_t t = ctx->rk[i][k];
483 ctx->rk[i][k] = ctx->rk[j][k];
484 ctx->rk[j][k] = t;
485 }
486 }
487
488 /* apply affine transform to middle keys */
489 for (i = 1; i < ctx->nr; i++) {
490 aria_a(&ctx->rk[i][0], &ctx->rk[i][1],
491 &ctx->rk[i][2], &ctx->rk[i][3]);
492 }
493
494 return 0;
495}
496
497/*
498 * Encrypt a block
499 */
500int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
501 const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
502 unsigned char output[MBEDTLS_ARIA_BLOCKSIZE])
503{
504 int i;
505
506 uint32_t a, b, c, d;
507 ARIA_VALIDATE_RET(ctx != NULL);
508 ARIA_VALIDATE_RET(input != NULL);
509 ARIA_VALIDATE_RET(output != NULL);
510
511 a = MBEDTLS_GET_UINT32_LE(input, 0);
512 b = MBEDTLS_GET_UINT32_LE(input, 4);
513 c = MBEDTLS_GET_UINT32_LE(input, 8);
514 d = MBEDTLS_GET_UINT32_LE(input, 12);
515
516 i = 0;
517 while (1) {
518 a ^= ctx->rk[i][0];
519 b ^= ctx->rk[i][1];
520 c ^= ctx->rk[i][2];
521 d ^= ctx->rk[i][3];
522 i++;
523
524 aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2);
525 aria_a(&a, &b, &c, &d);
526
527 a ^= ctx->rk[i][0];
528 b ^= ctx->rk[i][1];
529 c ^= ctx->rk[i][2];
530 d ^= ctx->rk[i][3];
531 i++;
532
533 aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2);
534 if (i >= ctx->nr) {
535 break;
536 }
537 aria_a(&a, &b, &c, &d);
538 }
539
540 /* final key mixing */
541 a ^= ctx->rk[i][0];
542 b ^= ctx->rk[i][1];
543 c ^= ctx->rk[i][2];
544 d ^= ctx->rk[i][3];
545
546 MBEDTLS_PUT_UINT32_LE(a, output, 0);
547 MBEDTLS_PUT_UINT32_LE(b, output, 4);
548 MBEDTLS_PUT_UINT32_LE(c, output, 8);
549 MBEDTLS_PUT_UINT32_LE(d, output, 12);
550
551 return 0;
552}
553
554/* Initialize context */
555void mbedtls_aria_init(mbedtls_aria_context *ctx)
556{
557 ARIA_VALIDATE(ctx != NULL);
558 memset(ctx, 0, sizeof(mbedtls_aria_context));
559}
560
561/* Clear context */
562void mbedtls_aria_free(mbedtls_aria_context *ctx)
563{
564 if (ctx == NULL) {
565 return;
566 }
567
568 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aria_context));
569}
570
571#if defined(MBEDTLS_CIPHER_MODE_CBC)
572/*
573 * ARIA-CBC buffer encryption/decryption
574 */
575int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
576 int mode,
577 size_t length,
578 unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
579 const unsigned char *input,
580 unsigned char *output)
581{
582 int i;
583 unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
584
585 ARIA_VALIDATE_RET(ctx != NULL);
586 ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
587 mode == MBEDTLS_ARIA_DECRYPT);
588 ARIA_VALIDATE_RET(length == 0 || input != NULL);
589 ARIA_VALIDATE_RET(length == 0 || output != NULL);
590 ARIA_VALIDATE_RET(iv != NULL);
591
592 if (length % MBEDTLS_ARIA_BLOCKSIZE) {
593 return MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH;
594 }
595
596 if (mode == MBEDTLS_ARIA_DECRYPT) {
597 while (length > 0) {
598 memcpy(temp, input, MBEDTLS_ARIA_BLOCKSIZE);
599 mbedtls_aria_crypt_ecb(ctx, input, output);
600
601 for (i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++) {
602 output[i] = (unsigned char) (output[i] ^ iv[i]);
603 }
604
605 memcpy(iv, temp, MBEDTLS_ARIA_BLOCKSIZE);
606
607 input += MBEDTLS_ARIA_BLOCKSIZE;
608 output += MBEDTLS_ARIA_BLOCKSIZE;
609 length -= MBEDTLS_ARIA_BLOCKSIZE;
610 }
611 } else {
612 while (length > 0) {
613 for (i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++) {
614 output[i] = (unsigned char) (input[i] ^ iv[i]);
615 }
616
617 mbedtls_aria_crypt_ecb(ctx, output, output);
618 memcpy(iv, output, MBEDTLS_ARIA_BLOCKSIZE);
619
620 input += MBEDTLS_ARIA_BLOCKSIZE;
621 output += MBEDTLS_ARIA_BLOCKSIZE;
622 length -= MBEDTLS_ARIA_BLOCKSIZE;
623 }
624 }
625
626 return 0;
627}
628#endif /* MBEDTLS_CIPHER_MODE_CBC */
629
630#if defined(MBEDTLS_CIPHER_MODE_CFB)
631/*
632 * ARIA-CFB128 buffer encryption/decryption
633 */
634int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
635 int mode,
636 size_t length,
637 size_t *iv_off,
638 unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
639 const unsigned char *input,
640 unsigned char *output)
641{
642 unsigned char c;
643 size_t n;
644
645 ARIA_VALIDATE_RET(ctx != NULL);
646 ARIA_VALIDATE_RET(mode == MBEDTLS_ARIA_ENCRYPT ||
647 mode == MBEDTLS_ARIA_DECRYPT);
648 ARIA_VALIDATE_RET(length == 0 || input != NULL);
649 ARIA_VALIDATE_RET(length == 0 || output != NULL);
650 ARIA_VALIDATE_RET(iv != NULL);
651 ARIA_VALIDATE_RET(iv_off != NULL);
652
653 n = *iv_off;
654
655 /* An overly large value of n can lead to an unlimited
656 * buffer overflow. Therefore, guard against this
657 * outside of parameter validation. */
658 if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
659 return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
660 }
661
662 if (mode == MBEDTLS_ARIA_DECRYPT) {
663 while (length--) {
664 if (n == 0) {
665 mbedtls_aria_crypt_ecb(ctx, iv, iv);
666 }
667
668 c = *input++;
669 *output++ = c ^ iv[n];
670 iv[n] = c;
671
672 n = (n + 1) & 0x0F;
673 }
674 } else {
675 while (length--) {
676 if (n == 0) {
677 mbedtls_aria_crypt_ecb(ctx, iv, iv);
678 }
679
680 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
681
682 n = (n + 1) & 0x0F;
683 }
684 }
685
686 *iv_off = n;
687
688 return 0;
689}
690#endif /* MBEDTLS_CIPHER_MODE_CFB */
691
692#if defined(MBEDTLS_CIPHER_MODE_CTR)
693/*
694 * ARIA-CTR buffer encryption/decryption
695 */
696int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
697 size_t length,
698 size_t *nc_off,
699 unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
700 unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
701 const unsigned char *input,
702 unsigned char *output)
703{
704 int c, i;
705 size_t n;
706
707 ARIA_VALIDATE_RET(ctx != NULL);
708 ARIA_VALIDATE_RET(length == 0 || input != NULL);
709 ARIA_VALIDATE_RET(length == 0 || output != NULL);
710 ARIA_VALIDATE_RET(nonce_counter != NULL);
711 ARIA_VALIDATE_RET(stream_block != NULL);
712 ARIA_VALIDATE_RET(nc_off != NULL);
713
714 n = *nc_off;
715 /* An overly large value of n can lead to an unlimited
716 * buffer overflow. Therefore, guard against this
717 * outside of parameter validation. */
718 if (n >= MBEDTLS_ARIA_BLOCKSIZE) {
719 return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA;
720 }
721
722 while (length--) {
723 if (n == 0) {
724 mbedtls_aria_crypt_ecb(ctx, nonce_counter,
725 stream_block);
726
727 for (i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i--) {
728 if (++nonce_counter[i - 1] != 0) {
729 break;
730 }
731 }
732 }
733 c = *input++;
734 *output++ = (unsigned char) (c ^ stream_block[n]);
735
736 n = (n + 1) & 0x0F;
737 }
738
739 *nc_off = n;
740
741 return 0;
742}
743#endif /* MBEDTLS_CIPHER_MODE_CTR */
744#endif /* !MBEDTLS_ARIA_ALT */
745
746#if defined(MBEDTLS_SELF_TEST)
747
748/*
749 * Basic ARIA ECB test vectors from RFC 5794
750 */
751static const uint8_t aria_test1_ecb_key[32] = // test key
752{
753 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit
754 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
755 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit
756 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit
757};
758
759static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext
760{
761 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all
762 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes
763};
764
765static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext
766{
767 { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit
768 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
769 { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit
770 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
771 { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit
772 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
773};
774
775/*
776 * Mode tests from "Test Vectors for ARIA" Version 1.0
777 * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
778 */
779#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
780 defined(MBEDTLS_CIPHER_MODE_CTR))
781static const uint8_t aria_test2_key[32] =
782{
783 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit
784 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
785 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit
786 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit
787};
788
789static const uint8_t aria_test2_pt[48] =
790{
791 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all
792 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
793 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
794 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
795 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
796 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
797};
798#endif
799
800#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
801static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] =
802{
803 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB
804 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV
805};
806#endif
807
808#if defined(MBEDTLS_CIPHER_MODE_CBC)
809static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext
810{
811 { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key
812 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
813 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
814 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
815 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
816 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
817 { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key
818 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
819 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
820 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
821 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
822 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
823 { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key
824 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
825 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
826 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
827 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
828 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
829};
830#endif /* MBEDTLS_CIPHER_MODE_CBC */
831
832#if defined(MBEDTLS_CIPHER_MODE_CFB)
833static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext
834{
835 { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key
836 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
837 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
838 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
839 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
840 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
841 { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key
842 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
843 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
844 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
845 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
846 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
847 { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key
848 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
849 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
850 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
851 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
852 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
853};
854#endif /* MBEDTLS_CIPHER_MODE_CFB */
855
856#if defined(MBEDTLS_CIPHER_MODE_CTR)
857static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext
858{
859 { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key
860 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
861 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
862 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
863 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
864 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
865 { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key
866 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
867 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
868 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
869 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
870 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
871 { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key
872 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
873 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
874 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
875 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
876 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
877};
878#endif /* MBEDTLS_CIPHER_MODE_CFB */
879
880#define ARIA_SELF_TEST_ASSERT(cond) \
881 do { \
882 if (cond) { \
883 if (verbose) \
884 mbedtls_printf("failed\n"); \
885 goto exit; \
886 } else { \
887 if (verbose) \
888 mbedtls_printf("passed\n"); \
889 } \
890 } while (0)
891
892/*
893 * Checkup routine
894 */
895int mbedtls_aria_self_test(int verbose)
896{
897 int i;
898 uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
899 mbedtls_aria_context ctx;
900 int ret = 1;
901
902#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
903 size_t j;
904#endif
905
906#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
907 defined(MBEDTLS_CIPHER_MODE_CFB) || \
908 defined(MBEDTLS_CIPHER_MODE_CTR))
909 uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
910#endif
911
912 mbedtls_aria_init(&ctx);
913
914 /*
915 * Test set 1
916 */
917 for (i = 0; i < 3; i++) {
918 /* test ECB encryption */
919 if (verbose) {
920 mbedtls_printf(" ARIA-ECB-%d (enc): ", 128 + 64 * i);
921 }
922 mbedtls_aria_setkey_enc(&ctx, aria_test1_ecb_key, 128 + 64 * i);
923 mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_pt, blk);
924 ARIA_SELF_TEST_ASSERT(
925 memcmp(blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE)
926 != 0);
927
928 /* test ECB decryption */
929 if (verbose) {
930 mbedtls_printf(" ARIA-ECB-%d (dec): ", 128 + 64 * i);
931 }
932 mbedtls_aria_setkey_dec(&ctx, aria_test1_ecb_key, 128 + 64 * i);
933 mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_ct[i], blk);
934 ARIA_SELF_TEST_ASSERT(
935 memcmp(blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE)
936 != 0);
937 }
938 if (verbose) {
939 mbedtls_printf("\n");
940 }
941
942 /*
943 * Test set 2
944 */
945#if defined(MBEDTLS_CIPHER_MODE_CBC)
946 for (i = 0; i < 3; i++) {
947 /* Test CBC encryption */
948 if (verbose) {
949 mbedtls_printf(" ARIA-CBC-%d (enc): ", 128 + 64 * i);
950 }
951 mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
952 memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
953 memset(buf, 0x55, sizeof(buf));
954 mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
955 aria_test2_pt, buf);
956 ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cbc_ct[i], 48)
957 != 0);
958
959 /* Test CBC decryption */
960 if (verbose) {
961 mbedtls_printf(" ARIA-CBC-%d (dec): ", 128 + 64 * i);
962 }
963 mbedtls_aria_setkey_dec(&ctx, aria_test2_key, 128 + 64 * i);
964 memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
965 memset(buf, 0xAA, sizeof(buf));
966 mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
967 aria_test2_cbc_ct[i], buf);
968 ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
969 }
970 if (verbose) {
971 mbedtls_printf("\n");
972 }
973
974#endif /* MBEDTLS_CIPHER_MODE_CBC */
975
976#if defined(MBEDTLS_CIPHER_MODE_CFB)
977 for (i = 0; i < 3; i++) {
978 /* Test CFB encryption */
979 if (verbose) {
980 mbedtls_printf(" ARIA-CFB-%d (enc): ", 128 + 64 * i);
981 }
982 mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
983 memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
984 memset(buf, 0x55, sizeof(buf));
985 j = 0;
986 mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
987 aria_test2_pt, buf);
988 ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cfb_ct[i], 48) != 0);
989
990 /* Test CFB decryption */
991 if (verbose) {
992 mbedtls_printf(" ARIA-CFB-%d (dec): ", 128 + 64 * i);
993 }
994 mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
995 memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE);
996 memset(buf, 0xAA, sizeof(buf));
997 j = 0;
998 mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
999 iv, aria_test2_cfb_ct[i], buf);
1000 ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
1001 }
1002 if (verbose) {
1003 mbedtls_printf("\n");
1004 }
1005#endif /* MBEDTLS_CIPHER_MODE_CFB */
1006
1007#if defined(MBEDTLS_CIPHER_MODE_CTR)
1008 for (i = 0; i < 3; i++) {
1009 /* Test CTR encryption */
1010 if (verbose) {
1011 mbedtls_printf(" ARIA-CTR-%d (enc): ", 128 + 64 * i);
1012 }
1013 mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
1014 memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE); // IV = 0
1015 memset(buf, 0x55, sizeof(buf));
1016 j = 0;
1017 mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk,
1018 aria_test2_pt, buf);
1019 ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_ctr_ct[i], 48) != 0);
1020
1021 /* Test CTR decryption */
1022 if (verbose) {
1023 mbedtls_printf(" ARIA-CTR-%d (dec): ", 128 + 64 * i);
1024 }
1025 mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i);
1026 memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE); // IV = 0
1027 memset(buf, 0xAA, sizeof(buf));
1028 j = 0;
1029 mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk,
1030 aria_test2_ctr_ct[i], buf);
1031 ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0);
1032 }
1033 if (verbose) {
1034 mbedtls_printf("\n");
1035 }
1036#endif /* MBEDTLS_CIPHER_MODE_CTR */
1037
1038 ret = 0;
1039
1040exit:
1041 mbedtls_aria_free(&ctx);
1042 return ret;
1043}
1044
1045#endif /* MBEDTLS_SELF_TEST */
1046
1047#endif /* MBEDTLS_ARIA_C */
1048