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 |
60 | static 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) |
69 | static 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 |
111 | static 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) |
120 | static 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__) |
131 | static 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 | */ |
166 | static 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 | */ |
198 | static 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 | */ |
224 | static 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 | |
250 | static 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 | |
276 | static 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 | |
302 | static 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 | */ |
331 | static 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 | */ |
353 | static 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 | */ |
379 | static 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 | */ |
404 | int 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 | */ |
467 | int 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 | */ |
500 | int 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 */ |
555 | void 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 */ |
562 | void 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 | */ |
575 | int 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 | */ |
634 | int 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 | */ |
696 | int 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 | */ |
751 | static 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 | |
759 | static 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 | |
765 | static 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)) |
781 | static 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 | |
789 | static 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)) |
801 | static 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) |
809 | static 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) |
833 | static 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) |
857 | static 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 | */ |
895 | int 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 | |
1040 | exit: |
1041 | mbedtls_aria_free(&ctx); |
1042 | return ret; |
1043 | } |
1044 | |
1045 | #endif /* MBEDTLS_SELF_TEST */ |
1046 | |
1047 | #endif /* MBEDTLS_ARIA_C */ |
1048 | |