blob: f6ad7f126bd065f81c678eadd84f5ccdd06b13a6 [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é-Gonnardfb0e4f02018-02-26 16:08:40 +010088#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__)
89#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
90/* I couldn't find an Intel equivalent of ret16, so two instructions */
91#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) )
92#endif
93#endif /* MBEDTLS_HAVE_ASM && GNUC */
94#if !defined(ARIA_P1)
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010095#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +010096#endif
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +000097
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +010098/*
99 * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
100 *
101 * This is submatrix P2 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100102 *
103 * Common compilers will translate this to a single instruction.
Manuel Pégourié-Gonnard35ad8912018-02-26 11:59:16 +0100104 */
105#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000106
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100107/*
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100108 * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
109 *
110 * This is submatrix P3 in [1] Appendix B.1
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100111 *
112 * Some compilers fail to translate this to a single instruction,
113 * so let's provide asm versions for common platforms with C fallback.
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100114 */
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100115#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__)
116#if defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
117static inline uint32_t aria_p3( uint32_t x )
118{
119 asm( "bswap %0" : "=r" (x) : "0" (x) );
120 return( x );
121}
122#define ARIA_P3 aria_p3
123#endif
124#endif /* MBEDTLS_HAVE_ASM && GNUC */
125#if !defined(ARIA_P3)
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100126#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) )
Manuel Pégourié-Gonnardfb0e4f02018-02-26 16:08:40 +0100127#endif
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100128
129/*
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100130 * ARIA Affine Transform
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +0100131 * (a, b, c, d) = state in/out
132 *
133 * If we denote the first by of input by 0, ..., the last byte by f,
134 * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
135 *
136 * Reading [1] 2.4 or [2] 2.4.3 in colums and performing simple
137 * rearrangements on adjacent pairs, output is:
138 *
139 * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
140 * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
141 * b = 0101 + 2323 + 5476 + 8998 + baab + ecec + ffdd
142 * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
143 * c = 0022 + 1133 + 4545 + 7667 + ab89 + dcdc + fefe
144 * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
145 * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cedf
146 * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
147 *
148 * Note: another presentation of the A transform can be found as the first
149 * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
150 * The implementation below uses only P1 and P2 as they are sufficient.
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100151 */
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100152static inline void aria_a( uint32_t *a, uint32_t *b,
153 uint32_t *c, uint32_t *d )
154{
155 uint32_t ta, tb, tc;
Manuel Pégourié-Gonnardf205a012018-02-26 14:10:23 +0100156 ta = *b; // 4567
157 *b = *a; // 0123
158 *a = ARIA_P2( ta ); // 6745
159 tb = ARIA_P2( *d ); // efcd
160 *d = ARIA_P1( *c ); // 98ba
161 *c = ARIA_P1( tb ); // fedc
162 ta ^= *d; // 4567+98ba
163 tc = ARIA_P2( *b ); // 2301
164 ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc
165 tb ^= ARIA_P2( *d ); // ba98+efcd
166 tc ^= ARIA_P1( *a ); // 2301+7654
167 *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
168 tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc
169 *a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
170 ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe
171 *d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT
172 tc = ARIA_P2( tc ); // 0123+5476
173 *c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000174}
175
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100176/*
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100177 * ARIA Substitution Layer SL1 / SL2
178 * (a, b, c, d) = state in/out
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100179 * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100180 *
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100181 * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
182 * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100183 */
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100184static inline void aria_sl( uint32_t *a, uint32_t *b,
185 uint32_t *c, uint32_t *d,
186 const uint8_t sa[0x100], const uint8_t sb[0x100],
187 const uint8_t sc[0x100], const uint8_t sd[0x100] )
Manuel Pégourié-Gonnard8c76a942018-02-21 12:03:22 +0100188{
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100189 *a = ( (uint32_t) sa[ *a & 0xFF]) ^
190 (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^
191 (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
192 (((uint32_t) sd[ *a >> 24 ]) << 24);
193 *b = ( (uint32_t) sa[ *b & 0xFF]) ^
194 (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^
195 (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
196 (((uint32_t) sd[ *b >> 24 ]) << 24);
197 *c = ( (uint32_t) sa[ *c & 0xFF]) ^
198 (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^
199 (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
200 (((uint32_t) sd[ *c >> 24 ]) << 24);
201 *d = ( (uint32_t) sa[ *d & 0xFF]) ^
202 (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^
203 (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
204 (((uint32_t) sd[ *d >> 24 ]) << 24);
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000205}
206
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100207/*
208 * S-Boxes
209 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000210static const uint8_t aria_sb1[0x100] =
211{
212 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
213 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
214 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
215 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
216 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
217 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
218 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
219 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
220 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
221 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
222 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
223 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
224 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
225 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
226 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
227 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
228 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
229 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
230 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
231 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
232 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
233 0xB0, 0x54, 0xBB, 0x16
234};
235
236static const uint8_t aria_sb2[0x100] =
237{
238 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
239 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
240 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
241 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
242 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
243 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
244 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
245 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
246 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
247 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
248 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
249 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
250 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
251 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
252 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
253 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
254 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
255 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
256 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
257 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
258 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
259 0xAF, 0xBA, 0xB5, 0x81
260};
261
262static const uint8_t aria_is1[0x100] =
263{
264 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
265 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
266 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
267 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
268 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
269 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
270 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
271 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
272 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
273 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
274 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
275 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
276 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
277 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
278 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
279 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
280 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
281 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
282 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
283 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
284 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
285 0x55, 0x21, 0x0C, 0x7D
286};
287
288static const uint8_t aria_is2[0x100] =
289{
290 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
291 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
292 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
293 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
294 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
295 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
296 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
297 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
298 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
299 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
300 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
301 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
302 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
303 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
304 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
305 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
306 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
307 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
308 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
309 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
310 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
311 0x03, 0xA2, 0xAC, 0x60
312};
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000313
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100314/*
315 * Helper for key schedule: r = FO( p, k ) ^ x
316 */
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100317static void aria_fo_xor( uint32_t r[4],
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000318 const uint32_t p[4], const uint32_t k[4], const uint32_t x[4] )
319{
320 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000321
322 a = p[0] ^ k[0];
323 b = p[1] ^ k[1];
324 c = p[2] ^ k[2];
325 d = p[3] ^ k[3];
326
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100327 aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
328 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000329
330 r[0] = a ^ x[0];
331 r[1] = b ^ x[1];
332 r[2] = c ^ x[2];
333 r[3] = d ^ x[3];
334}
335
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100336/*
337 * Helper for key schedule: r = FE( p, k ) ^ x
338 */
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100339static void aria_fe_xor(uint32_t r[4],
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000340 const uint32_t p[4], const uint32_t k[4], const uint32_t x[4] )
341{
342 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000343
344 a = p[0] ^ k[0];
345 b = p[1] ^ k[1];
346 c = p[2] ^ k[2];
347 d = p[3] ^ k[3];
348
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100349 aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
350 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000351
352 r[0] = a ^ x[0];
353 r[1] = b ^ x[1];
354 r[2] = c ^ x[2];
355 r[3] = d ^ x[3];
356}
357
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100358/*
359 * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
360 *
361 * We chose to store bytes into 32-bit words in little-endian format (see
362 * GET/PUT_UINT32_LE) so we need to reverse bytes here.
363 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000364static void aria_rot128(uint32_t r[4], const uint32_t a[4],
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100365 const uint32_t b[4], uint8_t n)
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000366{
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100367 uint8_t i, j;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000368 uint32_t t, u;
369
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100370 const uint8_t n1 = n % 32; // bit offset
371 const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100372
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100373 j = (n / 32) % 4; // initial word offset
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100374 t = ARIA_P3( b[j] ); // big endian
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000375 for( i = 0; i < 4; i++ )
376 {
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100377 j = (j + 1) % 4; // get next word, big endian
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100378 u = ARIA_P3( b[j] );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000379 t <<= n1; // rotate
Manuel Pégourié-Gonnardc76ceb62018-02-21 09:50:17 +0100380 t |= u >> n2;
Manuel Pégourié-Gonnardcac50082018-02-26 15:23:03 +0100381 t = ARIA_P3( t ); // back to little endian
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000382 r[i] = a[i] ^ t; // store
383 t = u; // move to next word
384 }
385}
386
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100387/*
388 * Set encryption key
389 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000390int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
391 const unsigned char *key, unsigned int keybits)
392{
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100393 /* round constant masks */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000394 const uint32_t rc[3][4] =
395 {
396 { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA },
397 { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF },
398 { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 }
399 };
400
401 int i;
402 uint32_t w[4][4], *w2;
403
404 if (keybits != 128 && keybits != 192 && keybits != 256)
405 return MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH;
406
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100407 /* Copy key to W0 (and potential remainder to W1) */
408 GET_UINT32_LE( w[0][0], key, 0 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000409 GET_UINT32_LE( w[0][1], key, 4 );
410 GET_UINT32_LE( w[0][2], key, 8 );
411 GET_UINT32_LE( w[0][3], key, 12 );
412
413 memset(w[1], 0, 16);
414 if( keybits >= 192 )
415 {
416 GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key
417 GET_UINT32_LE( w[1][1], key, 20 );
418 }
419 if( keybits == 256 )
420 {
421 GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key
422 GET_UINT32_LE( w[1][3], key, 28 );
423 }
424
425 i = (keybits - 128) >> 6; // index: 0, 1, 2
426 ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16
427
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100428 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 +0000429 i = i < 2 ? i + 1 : 0;
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100430 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 +0000431 i = i < 2 ? i + 1 : 0;
Manuel Pégourié-Gonnarda6d639e2018-02-20 13:45:44 +0100432 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 +0000433
434 for( i = 0; i < 4; i++ ) // create round keys
435 {
436 w2 = w[(i + 1) & 3];
Manuel Pégourié-Gonnard9cc89242018-02-21 09:44:29 +0100437 aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 );
438 aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 );
439 aria_rot128( ctx->rk[i + 8], w[i], w2, 61 );
440 aria_rot128( ctx->rk[i + 12], w[i], w2, 31 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000441 }
442 aria_rot128( ctx->rk[16], w[0], w[1], 19 );
443
444 return 0;
445}
446
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100447/*
448 * Set decryption key
449 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000450int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
451 const unsigned char *key, unsigned int keybits)
452{
453 int i, j, k, ret;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000454
455 ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
456 if( ret != 0 )
457 return ret;
458
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100459 /* flip the order of round keys */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000460 for( i = 0, j = ctx->nr; i < j; i++, j-- )
461 {
462 for( k = 0; k < 4; k++ )
463 {
Manuel Pégourié-Gonnarde1ad7492018-02-20 13:59:05 +0100464 uint32_t t = ctx->rk[i][k];
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000465 ctx->rk[i][k] = ctx->rk[j][k];
466 ctx->rk[j][k] = t;
467 }
468 }
469
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100470 /* apply affine transform to middle keys */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000471 for (i = 1; i < ctx->nr; i++ )
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100472 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 +0000473
474 return 0;
475}
476
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100477/*
478 * Encrypt a block
479 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000480int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
481 int mode,
482 const unsigned char input[16],
483 unsigned char output[16] )
484{
485 int i;
486
487 uint32_t a, b, c, d;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000488
489 ( (void) mode );
490
491 GET_UINT32_LE( a, input, 0 );
492 GET_UINT32_LE( b, input, 4 );
493 GET_UINT32_LE( c, input, 8 );
494 GET_UINT32_LE( d, input, 12 );
495
496 i = 0;
497 while (1)
498 {
499 a ^= ctx->rk[i][0];
500 b ^= ctx->rk[i][1];
501 c ^= ctx->rk[i][2];
502 d ^= ctx->rk[i][3];
503 i++;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100504
505 aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
506 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000507
508 a ^= ctx->rk[i][0];
509 b ^= ctx->rk[i][1];
510 c ^= ctx->rk[i][2];
511 d ^= ctx->rk[i][3];
512 i++;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100513
514 aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000515 if (i >= ctx->nr)
516 break;
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100517 aria_a( &a, &b, &c, &d );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000518 }
519
Manuel Pégourié-Gonnard64744f82018-02-21 12:35:19 +0100520 /* final key mixing */
521 a ^= ctx->rk[i][0];
522 b ^= ctx->rk[i][1];
523 c ^= ctx->rk[i][2];
524 d ^= ctx->rk[i][3];
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000525
526 PUT_UINT32_LE( a, output, 0 );
527 PUT_UINT32_LE( b, output, 4 );
528 PUT_UINT32_LE( c, output, 8 );
529 PUT_UINT32_LE( d, output, 12 );
530
531 return 0;
532}
533
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100534/* Initialize context */
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000535void mbedtls_aria_init( mbedtls_aria_context *ctx )
536{
537 memset( ctx, 0, sizeof( mbedtls_aria_context ) );
538}
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000539
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100540/* Clear context */
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000541void mbedtls_aria_free( mbedtls_aria_context *ctx )
542{
543 if( ctx == NULL )
544 return;
545
Manuel Pégourié-Gonnard56453932018-02-21 10:08:31 +0100546 mbedtls_zeroize( ctx, sizeof( mbedtls_aria_context ) );
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000547}
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000548
549#if defined(MBEDTLS_CIPHER_MODE_CBC)
550/*
551 * ARIA-CBC buffer encryption/decryption
552 */
553int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
554 int mode,
555 size_t length,
556 unsigned char iv[16],
557 const unsigned char *input,
558 unsigned char *output )
559{
560 int i;
561 unsigned char temp[16];
562
563 if( length % 16 )
564 return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
565
566 if( mode == MBEDTLS_ARIA_DECRYPT )
567 {
568 while( length > 0 )
569 {
570 memcpy( temp, input, 16 );
571 mbedtls_aria_crypt_ecb( ctx, mode, input, output );
572
573 for( i = 0; i < 16; i++ )
574 output[i] = (unsigned char)( output[i] ^ iv[i] );
575
576 memcpy( iv, temp, 16 );
577
578 input += 16;
579 output += 16;
580 length -= 16;
581 }
582 }
583 else
584 {
585 while( length > 0 )
586 {
587 for( i = 0; i < 16; i++ )
588 output[i] = (unsigned char)( input[i] ^ iv[i] );
589
590 mbedtls_aria_crypt_ecb( ctx, mode, output, output );
591 memcpy( iv, output, 16 );
592
593 input += 16;
594 output += 16;
595 length -= 16;
596 }
597 }
598
599 return( 0 );
600}
601#endif /* MBEDTLS_CIPHER_MODE_CBC */
602
603#if defined(MBEDTLS_CIPHER_MODE_CFB)
604/*
605 * ARIA-CFB128 buffer encryption/decryption
606 */
607int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
608 int mode,
609 size_t length,
610 size_t *iv_off,
611 unsigned char iv[16],
612 const unsigned char *input,
613 unsigned char *output )
614{
615 int c;
616 size_t n = *iv_off;
617
618 if( mode == MBEDTLS_ARIA_DECRYPT )
619 {
620 while( length-- )
621 {
622 if( n == 0 )
623 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, iv, iv );
624
625 c = *input++;
626 *output++ = (unsigned char)( c ^ iv[n] );
627 iv[n] = (unsigned char) c;
628
629 n = ( n + 1 ) & 0x0F;
630 }
631 }
632 else
633 {
634 while( length-- )
635 {
636 if( n == 0 )
637 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, iv, iv );
638
639 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
640
641 n = ( n + 1 ) & 0x0F;
642 }
643 }
644
645 *iv_off = n;
646
647 return( 0 );
648}
649#endif /* MBEDTLS_CIPHER_MODE_CFB */
650
651#if defined(MBEDTLS_CIPHER_MODE_CTR)
652/*
653 * ARIA-CTR buffer encryption/decryption
654 */
655int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
656 size_t length,
657 size_t *nc_off,
658 unsigned char nonce_counter[16],
659 unsigned char stream_block[16],
660 const unsigned char *input,
661 unsigned char *output )
662{
663 int c, i;
664 size_t n = *nc_off;
665
666 while( length-- )
667 {
668 if( n == 0 ) {
669 mbedtls_aria_crypt_ecb( ctx, MBEDTLS_ARIA_ENCRYPT, nonce_counter,
670 stream_block );
671
672 for( i = 16; i > 0; i-- )
673 if( ++nonce_counter[i - 1] != 0 )
674 break;
675 }
676 c = *input++;
677 *output++ = (unsigned char)( c ^ stream_block[n] );
678
679 n = ( n + 1 ) & 0x0F;
680 }
681
682 *nc_off = n;
683
684 return( 0 );
685}
686#endif /* MBEDTLS_CIPHER_MODE_CTR */
687#endif /* !MBEDTLS_ARIA_ALT */
688
689#if defined(MBEDTLS_SELF_TEST)
690
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100691/*
692 * Basic ARIA ECB test vectors from RFC 5794
693 */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000694static const uint8_t aria_test1_ecb_key[32] = // test key
695{
696 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit
697 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
698 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit
699 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit
700};
701
702static const uint8_t aria_test1_ecb_pt[16] = // plaintext
703{
704 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all
705 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes
706};
707
708static const uint8_t aria_test1_ecb_ct[3][16] = // ciphertext
709{
710 { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit
711 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
712 { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit
713 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
714 { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit
715 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
716};
717
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100718/*
719 * Mode tests from "Test Vectors for ARIA" Version 1.0
720 * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
721 */
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000722#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000723 defined(MBEDTLS_CIPHER_MODE_CTR))
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000724static const uint8_t aria_test2_key[32] =
725{
726 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit
727 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
728 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit
729 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit
730};
731
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000732static const uint8_t aria_test2_pt[48] =
733{
734 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all
735 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
736 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
737 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
738 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
739 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
740};
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000741#endif
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000742
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000743#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
744static const uint8_t aria_test2_iv[16] =
745{
746 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB
747 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV
748};
749#endif
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000750
751#if defined(MBEDTLS_CIPHER_MODE_CBC)
752static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertxt
753{
754 { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key
755 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
756 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
757 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
758 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
759 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
760 { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key
761 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
762 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
763 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
764 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
765 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
766 { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key
767 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
768 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
769 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
770 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
771 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
772};
773#endif /* MBEDTLS_CIPHER_MODE_CBC */
774
775#if defined(MBEDTLS_CIPHER_MODE_CFB)
776static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertxt
777{
778 { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key
779 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
780 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
781 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
782 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
783 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
784 { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key
785 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
786 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
787 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
788 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
789 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
790 { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key
791 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
792 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
793 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
794 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
795 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
796};
797#endif /* MBEDTLS_CIPHER_MODE_CFB */
798
799#if defined(MBEDTLS_CIPHER_MODE_CTR)
800static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertxt
801{
802 { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key
803 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
804 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
805 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
806 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
807 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
808 { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key
809 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
810 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
811 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
812 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
813 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
814 { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key
815 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
816 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
817 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
818 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
819 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
820};
821#endif /* MBEDTLS_CIPHER_MODE_CFB */
822
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000823#define ARIA_SELF_TEST_IF_FAIL \
824 { \
825 if( verbose ) \
826 printf( "failed\n" ); \
827 return( 1 ); \
828 } else { \
829 if( verbose ) \
830 printf( "passed\n" ); \
831 }
832
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100833/*
834 * Checkup routine
835 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000836int mbedtls_aria_self_test( int verbose )
837{
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000838 int i;
839 uint8_t blk[16];
840 mbedtls_aria_context ctx;
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000841
Markku-Juhani O. Saarinen6ba68d42017-12-01 14:26:21 +0000842#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
843 size_t j;
Markku-Juhani O. Saarinen3c0b53b2017-11-30 16:00:34 +0000844#endif
845
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000846#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
847 defined(MBEDTLS_CIPHER_MODE_CFB) || \
848 defined(MBEDTLS_CIPHER_MODE_CTR))
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000849 uint8_t buf[48], iv[16];
850#endif
851
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100852 /*
853 * Test set 1
854 */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000855 for( i = 0; i < 3; i++ )
856 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100857 /* test ECB encryption */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000858 if( verbose )
859 printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i);
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000860 mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000861 mbedtls_aria_crypt_ecb( &ctx, MBEDTLS_ARIA_ENCRYPT,
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000862 aria_test1_ecb_pt, blk );
863 if( memcmp( blk, aria_test1_ecb_ct[i], 16 ) != 0 )
864 ARIA_SELF_TEST_IF_FAIL;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000865
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100866 /* test ECB decryption */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000867 if( verbose )
868 printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i);
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000869 mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000870 mbedtls_aria_crypt_ecb( &ctx, MBEDTLS_ARIA_DECRYPT,
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000871 aria_test1_ecb_ct[i], blk );
872 if (memcmp( blk, aria_test1_ecb_pt, 16 ) != 0)
873 ARIA_SELF_TEST_IF_FAIL;
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000874 }
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000875 if( verbose )
876 printf("\n");
877
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100878 /*
879 * Test set 2
880 */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000881#if defined(MBEDTLS_CIPHER_MODE_CBC)
882 for( i = 0; i < 3; i++ )
883 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100884 /* Test CBC encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000885 if( verbose )
886 printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i);
887 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
888 memcpy( iv, aria_test2_iv, 16 );
889 memset( buf, 0x55, sizeof(buf) );
890 mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
891 aria_test2_pt, buf );
892 if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
893 ARIA_SELF_TEST_IF_FAIL;
894
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100895 /* Test CBC decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000896 if( verbose )
897 printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i);
898 mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i );
899 memcpy( iv, aria_test2_iv, 16 );
900 memset( buf, 0xAA, sizeof(buf) );
901 mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
902 aria_test2_cbc_ct[i], buf );
903 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
904 ARIA_SELF_TEST_IF_FAIL;
905 }
906 if( verbose )
907 printf("\n");
908
909#endif /* MBEDTLS_CIPHER_MODE_CBC */
910
911#if defined(MBEDTLS_CIPHER_MODE_CFB)
912 for( i = 0; i < 3; i++ )
913 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100914 /* Test CFB encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000915 if( verbose )
916 printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i);
917 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
918 memcpy( iv, aria_test2_iv, 16 );
919 memset( buf, 0x55, sizeof(buf) );
920 j = 0;
921 mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
922 aria_test2_pt, buf );
923 if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
924 ARIA_SELF_TEST_IF_FAIL;
925
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100926 /* Test CFB decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000927 if( verbose )
928 printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i);
929 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
930 memcpy( iv, aria_test2_iv, 16 );
931 memset( buf, 0xAA, sizeof(buf) );
932 j = 0;
933 mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
934 iv, aria_test2_cfb_ct[i], buf );
935 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
936 ARIA_SELF_TEST_IF_FAIL;
937 }
938 if( verbose )
939 printf("\n");
940#endif /* MBEDTLS_CIPHER_MODE_CFB */
941
942#if defined(MBEDTLS_CIPHER_MODE_CTR)
943 for( i = 0; i < 3; i++ )
944 {
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100945 /* Test CTR encryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000946 if( verbose )
947 printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i);
948 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
949 memset( iv, 0, 16 ); // IV = 0
950 memset( buf, 0x55, sizeof(buf) );
951 j = 0;
952 mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
953 aria_test2_pt, buf );
954 if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
955 ARIA_SELF_TEST_IF_FAIL;
956
Manuel Pégourié-Gonnarda41ecda2018-02-21 10:33:26 +0100957 /* Test CTR decryption */
Markku-Juhani O. Saarinen259fa602017-11-30 15:48:37 +0000958 if( verbose )
959 printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i);
960 mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
961 memset( iv, 0, 16 ); // IV = 0
962 memset( buf, 0xAA, sizeof(buf) );
963 j = 0;
964 mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
965 aria_test2_ctr_ct[i], buf );
966 if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
967 ARIA_SELF_TEST_IF_FAIL;
968 }
969 if( verbose )
970 printf("\n");
971#endif /* MBEDTLS_CIPHER_MODE_CTR */
Markku-Juhani O. Saarinen41efbaa2017-11-30 11:37:55 +0000972
973 return( 0 );
974}
975
976#endif /* MBEDTLS_SELF_TEST */
977
978#endif /* MBEDTLS_ARIA_C */