blob: 1d1daa18af3b736e7877acdb355fe710cd5373e3 [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
60#ifndef GET_UINT32_LE
61#define GET_UINT32_LE(n,b,i) \
62{ \
63 (n) = ( (uint32_t) (b)[(i) ] ) \
64 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
65 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
66 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
67}
68#endif
69
70#ifndef PUT_UINT32_LE
71#define PUT_UINT32_LE(n,b,i) \
72{ \
73 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
74 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
75 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
76 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
77}
78#endif
79
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010080/*
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +010081 * 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 +010082 *
83 * This is submatrix P1 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +010084 *
85 * Common compilers fail to translate this to minimal number of instructions,
86 * so let's provide asm versions for common platforms with C fallback.
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010087 */
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +010088#if defined(MBEDTLS_HAVE_ASM)
89#if defined(__arm__)
90/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
91#if defined(__GNUC__) && \
92 ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
93static inline uint32_t aria_p1( uint32_t x )
94{
95 uint32_t r;
96 asm( "rev16 %0, %1" : "=l" (r) : "l" (x) );
97 return( r );
98}
99#define ARIA_P1 aria_p1
100#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000
101static __inline uint32_t aria_p1( uint32_t x )
102{
103 uint32_t r;
104 __asm( "rev16 r, x" );
105 return( r );
106}
107#define ARIA_P1 aria_p1
108#endif
109#endif /* arm */
110#if defined(__GNUC__) && \
111 defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100112/* I couldn't find an Intel equivalent of ret16, so two instructions */
113#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) )
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +0100114#endif /* x86 gnuc */
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100115#endif /* MBEDTLS_HAVE_ASM && GNUC */
116#if !defined(ARIA_P1)
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100117#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100118#endif
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000119
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100120/*
121 * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
122 *
123 * This is submatrix P2 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100124 *
125 * Common compilers will translate this to a single instruction.
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100126 */
127#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000128
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100129/*
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100130 * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
131 *
132 * This is submatrix P3 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100133 *
134 * Some compilers fail to translate this to a single instruction,
135 * so let's provide asm versions for common platforms with C fallback.
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100136 */
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +0100137#if defined(MBEDTLS_HAVE_ASM)
138#if defined(__arm__)
139/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
140#if defined(__GNUC__) && \
141 ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
142static inline uint32_t aria_p3( uint32_t x )
143{
144 uint32_t r;
145 asm( "rev %0, %1" : "=l" (r) : "l" (x) );
146 return( r );
147}
148#define ARIA_P3 aria_p3
149#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000
150static __inline uint32_t aria_p3( uint32_t x )
151{
152 uint32_t r;
153 __asm( "rev r, x" );
154 return( r );
155}
156#define ARIA_P3 aria_p3
157#endif
158#endif /* arm */
159#if defined(__GNUC__) && \
160 defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100161static inline uint32_t aria_p3( uint32_t x )
162{
163 asm( "bswap %0" : "=r" (x) : "0" (x) );
164 return( x );
165}
166#define ARIA_P3 aria_p3
Manuel Pégourié-Gonnard377b2b62018-02-27 10:22:26 +0100167#endif /* x86 gnuc */
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100168#endif /* MBEDTLS_HAVE_ASM && GNUC */
169#if !defined(ARIA_P3)
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100170#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) )
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100171#endif
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100172
173/*
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100174 * ARIA Affine Transform
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +0100175 * (a, b, c, d) = state in/out
176 *
177 * If we denote the first by of input by 0, ..., the last byte by f,
178 * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
179 *
180 * Reading [1] 2.4 or [2] 2.4.3 in colums and performing simple
181 * rearrangements on adjacent pairs, output is:
182 *
183 * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
184 * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
185 * b = 0101 + 2323 + 5476 + 8998 + baab + ecec + ffdd
186 * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
187 * c = 0022 + 1133 + 4545 + 7667 + ab89 + dcdc + fefe
188 * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
189 * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cedf
190 * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
191 *
192 * Note: another presentation of the A transform can be found as the first
193 * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
194 * The implementation below uses only P1 and P2 as they are sufficient.
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100195 */
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100196static inline void aria_a( uint32_t *a, uint32_t *b,
197 uint32_t *c, uint32_t *d )
198{
199 uint32_t ta, tb, tc;
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +0100200 ta = *b; // 4567
201 *b = *a; // 0123
202 *a = ARIA_P2( ta ); // 6745
203 tb = ARIA_P2( *d ); // efcd
204 *d = ARIA_P1( *c ); // 98ba
205 *c = ARIA_P1( tb ); // fedc
206 ta ^= *d; // 4567+98ba
207 tc = ARIA_P2( *b ); // 2301
208 ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc
209 tb ^= ARIA_P2( *d ); // ba98+efcd
210 tc ^= ARIA_P1( *a ); // 2301+7654
211 *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
212 tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc
213 *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
214 ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe
215 *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT
216 tc = ARIA_P2( tc ); // 0123+5476
217 *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000218}
219
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100220/*
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100221 * ARIA Substitution Layer SL1 / SL2
222 * (a, b, c, d) = state in/out
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100223 * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100224 *
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100225 * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
226 * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100227 */
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100228static inline void aria_sl( uint32_t *a, uint32_t *b,
229 uint32_t *c, uint32_t *d,
230 const uint8_t sa[0x100], const uint8_t sb[0x100],
231 const uint8_t sc[0x100], const uint8_t sd[0x100] )
Manuel Pégourié-Gonnard8c76a942018-02-21 12:03:22 +0100232{
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100233 *a = ( (uint32_t) sa[ *a & 0xFF]) ^
234 (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^
235 (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
236 (((uint32_t) sd[ *a >> 24 ]) << 24);
237 *b = ( (uint32_t) sa[ *b & 0xFF]) ^
238 (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^
239 (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
240 (((uint32_t) sd[ *b >> 24 ]) << 24);
241 *c = ( (uint32_t) sa[ *c & 0xFF]) ^
242 (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^
243 (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
244 (((uint32_t) sd[ *c >> 24 ]) << 24);
245 *d = ( (uint32_t) sa[ *d & 0xFF]) ^
246 (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^
247 (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
248 (((uint32_t) sd[ *d >> 24 ]) << 24);
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000249}
250
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100251/*
252 * S-Boxes
253 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000254static const uint8_t aria_sb1[0x100] =
255{
256 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
257 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
258 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
259 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
260 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
261 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
262 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
263 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
264 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
265 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
266 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
267 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
268 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
269 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
270 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
271 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
272 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
273 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
274 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
275 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
276 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
277 0xB0, 0x54, 0xBB, 0x16
278};
279
280static const uint8_t aria_sb2[0x100] =
281{
282 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
283 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
284 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
285 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
286 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
287 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
288 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
289 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
290 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
291 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
292 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
293 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
294 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
295 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
296 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
297 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
298 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
299 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
300 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
301 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
302 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
303 0xAF, 0xBA, 0xB5, 0x81
304};
305
306static const uint8_t aria_is1[0x100] =
307{
308 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
309 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
310 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
311 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
312 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
313 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
314 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
315 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
316 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
317 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
318 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
319 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
320 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
321 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
322 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
323 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
324 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
325 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
326 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
327 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
328 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
329 0x55, 0x21, 0x0C, 0x7D
330};
331
332static const uint8_t aria_is2[0x100] =
333{
334 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
335 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
336 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
337 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
338 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
339 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
340 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
341 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
342 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
343 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
344 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
345 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
346 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
347 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
348 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
349 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
350 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
351 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
352 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
353 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
354 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
355 0x03, 0xA2, 0xAC, 0x60
356};
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000357
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100358/*
359 * Helper for key schedule: r = FO( p, k ) ^ x
360 */
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100361static void aria_fo_xor( uint32_t r[4],
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000362 const uint32_t p[4], const uint32_t k[4], const uint32_t x[4] )
363{
364 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000365
366 a = p[0] ^ k[0];
367 b = p[1] ^ k[1];
368 c = p[2] ^ k[2];
369 d = p[3] ^ k[3];
370
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100371 aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
372 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000373
374 r[0] = a ^ x[0];
375 r[1] = b ^ x[1];
376 r[2] = c ^ x[2];
377 r[3] = d ^ x[3];
378}
379
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100380/*
381 * Helper for key schedule: r = FE( p, k ) ^ x
382 */
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100383static void aria_fe_xor(uint32_t r[4],
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000384 const uint32_t p[4], const uint32_t k[4], const uint32_t x[4] )
385{
386 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000387
388 a = p[0] ^ k[0];
389 b = p[1] ^ k[1];
390 c = p[2] ^ k[2];
391 d = p[3] ^ k[3];
392
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100393 aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
394 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000395
396 r[0] = a ^ x[0];
397 r[1] = b ^ x[1];
398 r[2] = c ^ x[2];
399 r[3] = d ^ x[3];
400}
401
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100402/*
403 * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
404 *
405 * We chose to store bytes into 32-bit words in little-endian format (see
406 * GET/PUT_UINT32_LE) so we need to reverse bytes here.
407 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000408static void aria_rot128(uint32_t r[4], const uint32_t a[4],
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100409 const uint32_t b[4], uint8_t n)
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000410{
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100411 uint8_t i, j;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000412 uint32_t t, u;
413
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100414 const uint8_t n1 = n % 32; // bit offset
415 const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100416
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100417 j = (n / 32) % 4; // initial word offset
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100418 t = ARIA_P3( b[j] ); // big endian
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000419 for( i = 0; i < 4; i++ )
420 {
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100421 j = (j + 1) % 4; // get next word, big endian
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100422 u = ARIA_P3( b[j] );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000423 t <<= n1; // rotate
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100424 t |= u >> n2;
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100425 t = ARIA_P3( t ); // back to little endian
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000426 r[i] = a[i] ^ t; // store
427 t = u; // move to next word
428 }
429}
430
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100431/*
432 * Set encryption key
433 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000434int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
435 const unsigned char *key, unsigned int keybits)
436{
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100437 /* round constant masks */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000438 const uint32_t rc[3][4] =
439 {
440 { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA },
441 { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF },
442 { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 }
443 };
444
445 int i;
446 uint32_t w[4][4], *w2;
447
448 if (keybits != 128 && keybits != 192 && keybits != 256)
449 return MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH;
450
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100451 /* Copy key to W0 (and potential remainder to W1) */
452 GET_UINT32_LE( w[0][0], key, 0 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000453 GET_UINT32_LE( w[0][1], key, 4 );
454 GET_UINT32_LE( w[0][2], key, 8 );
455 GET_UINT32_LE( w[0][3], key, 12 );
456
457 memset(w[1], 0, 16);
458 if( keybits >= 192 )
459 {
460 GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key
461 GET_UINT32_LE( w[1][1], key, 20 );
462 }
463 if( keybits == 256 )
464 {
465 GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key
466 GET_UINT32_LE( w[1][3], key, 28 );
467 }
468
469 i = (keybits - 128) >> 6; // index: 0, 1, 2
470 ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16
471
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100472 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 +0000473 i = i < 2 ? i + 1 : 0;
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100474 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 +0000475 i = i < 2 ? i + 1 : 0;
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100476 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 +0000477
478 for( i = 0; i < 4; i++ ) // create round keys
479 {
480 w2 = w[(i + 1) & 3];
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100481 aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 );
482 aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 );
483 aria_rot128( ctx->rk[i + 8], w[i], w2, 61 );
484 aria_rot128( ctx->rk[i + 12], w[i], w2, 31 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000485 }
486 aria_rot128( ctx->rk[16], w[0], w[1], 19 );
487
488 return 0;
489}
490
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100491/*
492 * Set decryption key
493 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000494int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
495 const unsigned char *key, unsigned int keybits)
496{
497 int i, j, k, ret;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000498
499 ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
500 if( ret != 0 )
501 return ret;
502
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100503 /* flip the order of round keys */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000504 for( i = 0, j = ctx->nr; i < j; i++, j-- )
505 {
506 for( k = 0; k < 4; k++ )
507 {
Manuel Pégourié-Gonnarde1ad7492018-02-20 13:59:05 +0100508 uint32_t t = ctx->rk[i][k];
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000509 ctx->rk[i][k] = ctx->rk[j][k];
510 ctx->rk[j][k] = t;
511 }
512 }
513
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100514 /* apply affine transform to middle keys */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000515 for (i = 1; i < ctx->nr; i++ )
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100516 aria_a( &ctx->rk[i][0], &ctx->rk[i][1], &ctx->rk[i][2], &ctx->rk[i][3] );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000517
518 return 0;
519}
520
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100521/*
522 * Encrypt a block
523 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000524int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
525 int mode,
526 const unsigned char input[16],
527 unsigned char output[16] )
528{
529 int i;
530
531 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000532
533 ( (void) mode );
534
535 GET_UINT32_LE( a, input, 0 );
536 GET_UINT32_LE( b, input, 4 );
537 GET_UINT32_LE( c, input, 8 );
538 GET_UINT32_LE( d, input, 12 );
539
540 i = 0;
541 while (1)
542 {
543 a ^= ctx->rk[i][0];
544 b ^= ctx->rk[i][1];
545 c ^= ctx->rk[i][2];
546 d ^= ctx->rk[i][3];
547 i++;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100548
549 aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
550 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000551
552 a ^= ctx->rk[i][0];
553 b ^= ctx->rk[i][1];
554 c ^= ctx->rk[i][2];
555 d ^= ctx->rk[i][3];
556 i++;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100557
558 aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000559 if (i >= ctx->nr)
560 break;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100561 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000562 }
563
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100564 /* final key mixing */
565 a ^= ctx->rk[i][0];
566 b ^= ctx->rk[i][1];
567 c ^= ctx->rk[i][2];
568 d ^= ctx->rk[i][3];
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000569
570 PUT_UINT32_LE( a, output, 0 );
571 PUT_UINT32_LE( b, output, 4 );
572 PUT_UINT32_LE( c, output, 8 );
573 PUT_UINT32_LE( d, output, 12 );
574
575 return 0;
576}
577
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100578/* Initialize context */
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000579void mbedtls_aria_init( mbedtls_aria_context *ctx )
580{
581 memset( ctx, 0, sizeof( mbedtls_aria_context ) );
582}
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000583
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100584/* Clear context */
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000585void mbedtls_aria_free( mbedtls_aria_context *ctx )
586{
587 if( ctx == NULL )
588 return;
589
Manuel Pégourié-Gonnard56453932018-02-21 10:08:31 +0100590 mbedtls_zeroize( ctx, sizeof( mbedtls_aria_context ) );
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000591}
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000592
593#if defined(MBEDTLS_CIPHER_MODE_CBC)
594/*
595 * ARIA-CBC buffer encryption/decryption
596 */
597int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
598 int mode,
599 size_t length,
600 unsigned char iv[16],
601 const unsigned char *input,
602 unsigned char *output )
603{
604 int i;
605 unsigned char temp[16];
606
607 if( length % 16 )
608 return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
609
610 if( mode == MBEDTLS_ARIA_DECRYPT )
611 {
612 while( length > 0 )
613 {
614 memcpy( temp, input, 16 );
615 mbedtls_aria_crypt_ecb( ctx, mode, input, output );
616
617 for( i = 0; i < 16; i++ )
618 output[i] = (unsigned char)( output[i] ^ iv[i] );
619
620 memcpy( iv, temp, 16 );
621
622 input += 16;
623 output += 16;
624 length -= 16;
625 }
626 }
627 else
628 {
629 while( length > 0 )
630 {
631 for( i = 0; i < 16; i++ )
632 output[i] = (unsigned char)( input[i] ^ iv[i] );
633
634 mbedtls_aria_crypt_ecb( ctx, mode, output, output );
635 memcpy( iv, output, 16 );
636
637 input += 16;
638 output += 16;
639 length -= 16;
640 }
641 }
642
643 return( 0 );
644}
645#endif /* MBEDTLS_CIPHER_MODE_CBC */
646
647#if defined(MBEDTLS_CIPHER_MODE_CFB)
648/*
649 * ARIA-CFB128 buffer encryption/decryption
650 */
651int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
652 int mode,
653 size_t length,
654 size_t *iv_off,
655 unsigned char iv[16],
656 const unsigned char *input,
657 unsigned char *output )
658{
659 int c;
660 size_t n = *iv_off;
661
662 if( mode == MBEDTLS_ARIA_DECRYPT )
663 {
664 while( length-- )
665 {
666 if( n == 0 )
667 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, iv, iv );
668
669 c = *input++;
670 *output++ = (unsigned char)( c ^ iv[n] );
671 iv[n] = (unsigned char) c;
672
673 n = ( n + 1 ) & 0x0F;
674 }
675 }
676 else
677 {
678 while( length-- )
679 {
680 if( n == 0 )
681 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, iv, iv );
682
683 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
684
685 n = ( n + 1 ) & 0x0F;
686 }
687 }
688
689 *iv_off = n;
690
691 return( 0 );
692}
693#endif /* MBEDTLS_CIPHER_MODE_CFB */
694
695#if defined(MBEDTLS_CIPHER_MODE_CTR)
696/*
697 * ARIA-CTR buffer encryption/decryption
698 */
699int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
700 size_t length,
701 size_t *nc_off,
702 unsigned char nonce_counter[16],
703 unsigned char stream_block[16],
704 const unsigned char *input,
705 unsigned char *output )
706{
707 int c, i;
708 size_t n = *nc_off;
709
710 while( length-- )
711 {
712 if( n == 0 ) {
713 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, nonce_counter,
714 stream_block );
715
716 for( i = 16; i > 0; i-- )
717 if( ++nonce_counter[i - 1] != 0 )
718 break;
719 }
720 c = *input++;
721 *output++ = (unsigned char)( c ^ stream_block[n] );
722
723 n = ( n + 1 ) & 0x0F;
724 }
725
726 *nc_off = n;
727
728 return( 0 );
729}
730#endif /* MBEDTLS_CIPHER_MODE_CTR */
731#endif /* !MBEDTLS_ARIA_ALT */
732
733#if defined(MBEDTLS_SELF_TEST)
734
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100735/*
736 * Basic ARIA ECB test vectors from RFC 5794
737 */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000738static const uint8_t aria_test1_ecb_key[32] = // test key
739{
740 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit
741 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
742 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit
743 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit
744};
745
746static const uint8_t aria_test1_ecb_pt[16] = // plaintext
747{
748 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all
749 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes
750};
751
752static const uint8_t aria_test1_ecb_ct[3][16] = // ciphertext
753{
754 { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit
755 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
756 { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit
757 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
758 { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit
759 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
760};
761
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100762/*
763 * Mode tests from "Test Vectors for ARIA" Version 1.0
764 * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
765 */
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000766#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000767 defined(MBEDTLS_CIPHER_MODE_CTR))
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000768static const uint8_t aria_test2_key[32] =
769{
770 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit
771 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
772 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit
773 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit
774};
775
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000776static const uint8_t aria_test2_pt[48] =
777{
778 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all
779 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
780 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
781 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
782 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
783 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
784};
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000785#endif
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000786
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000787#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
788static const uint8_t aria_test2_iv[16] =
789{
790 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB
791 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV
792};
793#endif
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000794
795#if defined(MBEDTLS_CIPHER_MODE_CBC)
796static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertxt
797{
798 { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key
799 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
800 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
801 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
802 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
803 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
804 { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key
805 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
806 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
807 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
808 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
809 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
810 { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key
811 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
812 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
813 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
814 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
815 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
816};
817#endif /* MBEDTLS_CIPHER_MODE_CBC */
818
819#if defined(MBEDTLS_CIPHER_MODE_CFB)
820static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertxt
821{
822 { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key
823 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
824 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
825 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
826 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
827 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
828 { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key
829 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
830 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
831 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
832 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
833 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
834 { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key
835 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
836 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
837 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
838 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
839 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
840};
841#endif /* MBEDTLS_CIPHER_MODE_CFB */
842
843#if defined(MBEDTLS_CIPHER_MODE_CTR)
844static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertxt
845{
846 { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key
847 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
848 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
849 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
850 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
851 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
852 { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key
853 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
854 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
855 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
856 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
857 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
858 { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key
859 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
860 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
861 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
862 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
863 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
864};
865#endif /* MBEDTLS_CIPHER_MODE_CFB */
866
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000867#define ARIA_SELF_TEST_IF_FAIL \
868 { \
869 if( verbose ) \
870 printf( "failed\n" ); \
871 return( 1 ); \
872 } else { \
873 if( verbose ) \
874 printf( "passed\n" ); \
875 }
876
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100877/*
878 * Checkup routine
879 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000880int mbedtls_aria_self_test( int verbose )
881{
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000882 int i;
883 uint8_t blk[16];
884 mbedtls_aria_context ctx;
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000885
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000886#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
887 size_t j;
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000888#endif
889
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000890#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
891 defined(MBEDTLS_CIPHER_MODE_CFB) || \
892 defined(MBEDTLS_CIPHER_MODE_CTR))
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000893 uint8_t buf[48], iv[16];
894#endif
895
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100896 /*
897 * Test set 1
898 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000899 for( i = 0; i < 3; i++ )
900 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100901 /* test ECB encryption */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000902 if( verbose )
903 printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i);
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000904 mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000905 mbedtls_aria_crypt_ecb( &ctx, MBEDTLS_ARIA_ENCRYPT,
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000906 aria_test1_ecb_pt, blk );
907 if( memcmp( blk, aria_test1_ecb_ct[i], 16 ) != 0 )
908 ARIA_SELF_TEST_IF_FAIL;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000909
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100910 /* test ECB decryption */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000911 if( verbose )
912 printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i);
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000913 mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000914 mbedtls_aria_crypt_ecb( &ctx, MBEDTLS_ARIA_DECRYPT,
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000915 aria_test1_ecb_ct[i], blk );
916 if (memcmp( blk, aria_test1_ecb_pt, 16 ) != 0)
917 ARIA_SELF_TEST_IF_FAIL;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000918 }
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000919 if( verbose )
920 printf("\n");
921
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100922 /*
923 * Test set 2
924 */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000925#if defined(MBEDTLS_CIPHER_MODE_CBC)
926 for( i = 0; i < 3; i++ )
927 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100928 /* Test CBC encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000929 if( verbose )
930 printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i);
931 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
932 memcpy( iv, aria_test2_iv, 16 );
933 memset( buf, 0x55, sizeof(buf) );
934 mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
935 aria_test2_pt, buf );
936 if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
937 ARIA_SELF_TEST_IF_FAIL;
938
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100939 /* Test CBC decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000940 if( verbose )
941 printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i);
942 mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i );
943 memcpy( iv, aria_test2_iv, 16 );
944 memset( buf, 0xAA, sizeof(buf) );
945 mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
946 aria_test2_cbc_ct[i], buf );
947 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
948 ARIA_SELF_TEST_IF_FAIL;
949 }
950 if( verbose )
951 printf("\n");
952
953#endif /* MBEDTLS_CIPHER_MODE_CBC */
954
955#if defined(MBEDTLS_CIPHER_MODE_CFB)
956 for( i = 0; i < 3; i++ )
957 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100958 /* Test CFB encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000959 if( verbose )
960 printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i);
961 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
962 memcpy( iv, aria_test2_iv, 16 );
963 memset( buf, 0x55, sizeof(buf) );
964 j = 0;
965 mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
966 aria_test2_pt, buf );
967 if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
968 ARIA_SELF_TEST_IF_FAIL;
969
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100970 /* Test CFB decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000971 if( verbose )
972 printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i);
973 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
974 memcpy( iv, aria_test2_iv, 16 );
975 memset( buf, 0xAA, sizeof(buf) );
976 j = 0;
977 mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
978 iv, aria_test2_cfb_ct[i], buf );
979 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
980 ARIA_SELF_TEST_IF_FAIL;
981 }
982 if( verbose )
983 printf("\n");
984#endif /* MBEDTLS_CIPHER_MODE_CFB */
985
986#if defined(MBEDTLS_CIPHER_MODE_CTR)
987 for( i = 0; i < 3; i++ )
988 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100989 /* Test CTR encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000990 if( verbose )
991 printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i);
992 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
993 memset( iv, 0, 16 ); // IV = 0
994 memset( buf, 0x55, sizeof(buf) );
995 j = 0;
996 mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
997 aria_test2_pt, buf );
998 if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
999 ARIA_SELF_TEST_IF_FAIL;
1000
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +01001001 /* Test CTR decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +00001002 if( verbose )
1003 printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i);
1004 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
1005 memset( iv, 0, 16 ); // IV = 0
1006 memset( buf, 0xAA, sizeof(buf) );
1007 j = 0;
1008 mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
1009 aria_test2_ctr_ct[i], buf );
1010 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
1011 ARIA_SELF_TEST_IF_FAIL;
1012 }
1013 if( verbose )
1014 printf("\n");
1015#endif /* MBEDTLS_CIPHER_MODE_CTR */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +00001016
1017 return( 0 );
1018}
1019
1020#endif /* MBEDTLS_SELF_TEST */
1021
1022#endif /* MBEDTLS_ARIA_C */