blob: 6ef4c213345eb5d792c0b0d62bd7d9f5bf2841e8 [file] [log] [blame]
Paul Bakker38119b12009-01-10 23:31:23 +00001/*
2 * Camellia implementation
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Paul Bakker38119b12009-01-10 23:31:23 +000045 */
46/*
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000047 * The Camellia block cipher was designed by NTT and Mitsubishi Electric
48 * Corporation.
Paul Bakker38119b12009-01-10 23:31:23 +000049 *
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000050 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
Paul Bakker38119b12009-01-10 23:31:23 +000051 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Paul Bakker38119b12009-01-10 23:31:23 +000058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_CAMELLIA_C)
Paul Bakker38119b12009-01-10 23:31:23 +000060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/camellia.h"
Paul Bakker38119b12009-01-10 23:31:23 +000062
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <string.h>
Manuel Pégourié-Gonnard394608e2015-02-17 16:01:07 +010064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_SELF_TEST)
66#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068#else
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#define mbedtls_printf printf
71#endif /* MBEDTLS_PLATFORM_C */
72#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#if !defined(MBEDTLS_CAMELLIA_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020075
Paul Bakker34617722014-06-13 17:20:13 +020076/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077static void mbedtls_zeroize( void *v, size_t n ) {
Simon Butcher88ffc082016-05-20 00:00:37 +010078 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
Paul Bakker34617722014-06-13 17:20:13 +020079}
80
Paul Bakker38119b12009-01-10 23:31:23 +000081/*
82 * 32-bit integer manipulation macros (big endian)
83 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000084#ifndef GET_UINT32_BE
85#define GET_UINT32_BE(n,b,i) \
Paul Bakker38119b12009-01-10 23:31:23 +000086{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000087 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
88 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
89 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
90 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker38119b12009-01-10 23:31:23 +000091}
92#endif
93
Paul Bakker5c2364c2012-10-01 14:41:15 +000094#ifndef PUT_UINT32_BE
95#define PUT_UINT32_BE(n,b,i) \
Paul Bakker38119b12009-01-10 23:31:23 +000096{ \
97 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
98 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
99 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
100 (b)[(i) + 3] = (unsigned char) ( (n) ); \
101}
102#endif
103
104static const unsigned char SIGMA_CHARS[6][8] =
105{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000106 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
107 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
108 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
109 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
110 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
111 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +0000112};
113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
Paul Bakkerfa049db2009-01-12 22:12:03 +0000115
116static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +0000117{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000118 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
119 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
120 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
121 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
122 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
123 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
124 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
125 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
126 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
127 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
128 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
129 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
130 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
131 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
132 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
133 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
Paul Bakker38119b12009-01-10 23:31:23 +0000134};
135
136#define SBOX1(n) FSb[(n)]
137#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
138#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +0000139#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
140
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000142
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000143static const unsigned char FSb[256] =
144{
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200145 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
146 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
147 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
148 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
149 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
150 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
151 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
152 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
153 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
154 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
155 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
156 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
157 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
158 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
159 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
160 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000161};
162
163static const unsigned char FSb2[256] =
164{
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200165 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
166 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
167 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
168 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
169 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
170 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
171 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
172 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
173 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
174 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
175 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
176 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
177 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
178 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
179 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
180 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000181};
182
183static const unsigned char FSb3[256] =
184{
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200185 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
186 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
187 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
188 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
189 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
190 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
191 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
192 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
193 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
194 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
195 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
196 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
197 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
198 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
199 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
200 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000201};
202
203static const unsigned char FSb4[256] =
204{
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200205 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
206 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
207 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
208 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
209 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
210 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
211 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
212 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
213 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
214 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
215 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
216 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
217 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
218 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
219 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
220 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000221};
222
223#define SBOX1(n) FSb[(n)]
224#define SBOX2(n) FSb2[(n)]
225#define SBOX3(n) FSb3[(n)]
226#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000227
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000229
Paul Bakker38119b12009-01-10 23:31:23 +0000230static const unsigned char shifts[2][4][4] =
231{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000232 {
233 { 1, 1, 1, 1 }, /* KL */
234 { 0, 0, 0, 0 }, /* KR */
235 { 1, 1, 1, 1 }, /* KA */
236 { 0, 0, 0, 0 } /* KB */
237 },
238 {
239 { 1, 0, 1, 1 }, /* KL */
240 { 1, 1, 0, 1 }, /* KR */
241 { 1, 1, 1, 0 }, /* KA */
242 { 1, 1, 0, 1 } /* KB */
243 }
Paul Bakker38119b12009-01-10 23:31:23 +0000244};
245
Paul Bakker026c03b2009-03-28 17:53:03 +0000246static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000247{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000248 {
249 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
250 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
251 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
252 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
253 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
254 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
255 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
256 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
257 },
258 {
259 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
260 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
261 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
262 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
263 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
264 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
265 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
266 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
267 }
Paul Bakker38119b12009-01-10 23:31:23 +0000268};
269
Paul Bakker026c03b2009-03-28 17:53:03 +0000270static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000271{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000272 {
273 21, 22, 23, 20,
274 -1, -1, -1, -1,
275 18, 19, 16, 17,
276 11, 8, 9, 10,
277 15, 12, 13, 14
278 },
279 {
280 25, 26, 27, 24,
281 29, 30, 31, 28,
282 18, 19, 16, 17,
283 -1, -1, -1, -1,
284 -1, -1, -1, -1
285 }
Paul Bakker38119b12009-01-10 23:31:23 +0000286};
287
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000288/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000289#define ROTL(DEST, SRC, SHIFT) \
290{ \
291 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
292 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
293 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
294 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
Paul Bakker38119b12009-01-10 23:31:23 +0000295}
296
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000297#define FL(XL, XR, KL, KR) \
298{ \
299 (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \
300 (XL) = ((XR) | (KR)) ^ (XL); \
Paul Bakker38119b12009-01-10 23:31:23 +0000301}
Paul Bakker9af723c2014-05-01 13:03:14 +0200302
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000303#define FLInv(YL, YR, KL, KR) \
304{ \
305 (YL) = ((YR) | (KR)) ^ (YL); \
306 (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \
Paul Bakker38119b12009-01-10 23:31:23 +0000307}
Paul Bakker9af723c2014-05-01 13:03:14 +0200308
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000309#define SHIFT_AND_PLACE(INDEX, OFFSET) \
310{ \
311 TK[0] = KC[(OFFSET) * 4 + 0]; \
312 TK[1] = KC[(OFFSET) * 4 + 1]; \
313 TK[2] = KC[(OFFSET) * 4 + 2]; \
314 TK[3] = KC[(OFFSET) * 4 + 3]; \
315 \
Paul Bakker66d5d072014-06-17 16:39:18 +0200316 for( i = 1; i <= 4; i++ ) \
317 if( shifts[(INDEX)][(OFFSET)][i -1] ) \
318 ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000319 \
Paul Bakker66d5d072014-06-17 16:39:18 +0200320 for( i = 0; i < 20; i++ ) \
321 if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \
322 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \
323 } \
Paul Bakker38119b12009-01-10 23:31:23 +0000324}
325
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200326static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
327 uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000328{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000329 uint32_t I0, I1;
330 I0 = x[0] ^ k[0];
331 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000332
Manuel Pégourié-Gonnardb31b61b2014-11-10 13:05:43 +0100333 I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
334 ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
335 ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) |
336 ((uint32_t) SBOX4((I0 ) & 0xFF) );
337 I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
338 ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
339 ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) |
340 ((uint32_t) SBOX1((I1 ) & 0xFF) );
Paul Bakker38119b12009-01-10 23:31:23 +0000341
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000342 I0 ^= (I1 << 8) | (I1 >> 24);
343 I1 ^= (I0 << 16) | (I0 >> 16);
344 I0 ^= (I1 >> 8) | (I1 << 24);
345 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000346
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000347 z[0] ^= I1;
348 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000349}
350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200352{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200354}
355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356void mbedtls_camellia_free( mbedtls_camellia_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200357{
358 if( ctx == NULL )
359 return;
360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 mbedtls_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200362}
363
Paul Bakker38119b12009-01-10 23:31:23 +0000364/*
365 * Camellia key schedule (encryption)
366 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200368 unsigned int keybits )
Paul Bakker38119b12009-01-10 23:31:23 +0000369{
Paul Bakker23986e52011-04-24 08:57:21 +0000370 int idx;
371 size_t i;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000372 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000373 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000374 uint32_t SIGMA[6][2];
375 uint32_t KC[16];
376 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000377
378 RK = ctx->rk;
379
Paul Bakker66d5d072014-06-17 16:39:18 +0200380 memset( t, 0, 64 );
381 memset( RK, 0, sizeof(ctx->rk) );
Paul Bakker38119b12009-01-10 23:31:23 +0000382
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200383 switch( keybits )
Paul Bakker38119b12009-01-10 23:31:23 +0000384 {
385 case 128: ctx->nr = 3; idx = 0; break;
386 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000387 case 256: ctx->nr = 4; idx = 1; break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH );
Paul Bakker38119b12009-01-10 23:31:23 +0000389 }
390
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200391 for( i = 0; i < keybits / 8; ++i )
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000392 t[i] = key[i];
Paul Bakker38119b12009-01-10 23:31:23 +0000393
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200394 if( keybits == 192 ) {
Paul Bakker66d5d072014-06-17 16:39:18 +0200395 for( i = 0; i < 8; i++ )
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000396 t[24 + i] = ~t[16 + i];
Paul Bakker38119b12009-01-10 23:31:23 +0000397 }
398
Paul Bakker38119b12009-01-10 23:31:23 +0000399 /*
400 * Prepare SIGMA values
401 */
Paul Bakker66d5d072014-06-17 16:39:18 +0200402 for( i = 0; i < 6; i++ ) {
403 GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
404 GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
Paul Bakker38119b12009-01-10 23:31:23 +0000405 }
406
407 /*
408 * Key storage in KC
409 * Order: KL, KR, KA, KB
410 */
Paul Bakker66d5d072014-06-17 16:39:18 +0200411 memset( KC, 0, sizeof(KC) );
Paul Bakker38119b12009-01-10 23:31:23 +0000412
413 /* Store KL, KR */
Paul Bakker66d5d072014-06-17 16:39:18 +0200414 for( i = 0; i < 8; i++ )
415 GET_UINT32_BE( KC[i], t, i * 4 );
Paul Bakker38119b12009-01-10 23:31:23 +0000416
417 /* Generate KA */
Paul Bakker66d5d072014-06-17 16:39:18 +0200418 for( i = 0; i < 4; ++i )
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000419 KC[8 + i] = KC[i] ^ KC[4 + i];
Paul Bakker38119b12009-01-10 23:31:23 +0000420
Paul Bakker66d5d072014-06-17 16:39:18 +0200421 camellia_feistel( KC + 8, SIGMA[0], KC + 10 );
422 camellia_feistel( KC + 10, SIGMA[1], KC + 8 );
Paul Bakker38119b12009-01-10 23:31:23 +0000423
Paul Bakker66d5d072014-06-17 16:39:18 +0200424 for( i = 0; i < 4; ++i )
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000425 KC[8 + i] ^= KC[i];
Paul Bakker38119b12009-01-10 23:31:23 +0000426
Paul Bakker66d5d072014-06-17 16:39:18 +0200427 camellia_feistel( KC + 8, SIGMA[2], KC + 10 );
428 camellia_feistel( KC + 10, SIGMA[3], KC + 8 );
Paul Bakker38119b12009-01-10 23:31:23 +0000429
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200430 if( keybits > 128 ) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000431 /* Generate KB */
Paul Bakker66d5d072014-06-17 16:39:18 +0200432 for( i = 0; i < 4; ++i )
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000433 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Paul Bakker38119b12009-01-10 23:31:23 +0000434
Paul Bakker66d5d072014-06-17 16:39:18 +0200435 camellia_feistel( KC + 12, SIGMA[4], KC + 14 );
436 camellia_feistel( KC + 14, SIGMA[5], KC + 12 );
Paul Bakker38119b12009-01-10 23:31:23 +0000437 }
438
439 /*
440 * Generating subkeys
Paul Bakker9af723c2014-05-01 13:03:14 +0200441 */
Paul Bakker38119b12009-01-10 23:31:23 +0000442
443 /* Manipulating KL */
Paul Bakker66d5d072014-06-17 16:39:18 +0200444 SHIFT_AND_PLACE( idx, 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000445
446 /* Manipulating KR */
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200447 if( keybits > 128 ) {
Paul Bakker66d5d072014-06-17 16:39:18 +0200448 SHIFT_AND_PLACE( idx, 1 );
Paul Bakker38119b12009-01-10 23:31:23 +0000449 }
450
451 /* Manipulating KA */
Paul Bakker66d5d072014-06-17 16:39:18 +0200452 SHIFT_AND_PLACE( idx, 2 );
Paul Bakker38119b12009-01-10 23:31:23 +0000453
454 /* Manipulating KB */
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200455 if( keybits > 128 ) {
Paul Bakker66d5d072014-06-17 16:39:18 +0200456 SHIFT_AND_PLACE( idx, 3 );
Paul Bakker38119b12009-01-10 23:31:23 +0000457 }
458
459 /* Do transpositions */
Paul Bakker66d5d072014-06-17 16:39:18 +0200460 for( i = 0; i < 20; i++ ) {
461 if( transposes[idx][i] != -1 ) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000462 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
463 }
Paul Bakker38119b12009-01-10 23:31:23 +0000464 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000465
466 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000467}
468
469/*
470 * Camellia key schedule (decryption)
471 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200473 unsigned int keybits )
Paul Bakker38119b12009-01-10 23:31:23 +0000474{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200475 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000476 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000478 uint32_t *RK;
479 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_camellia_init( &cty );
Paul Bakker38119b12009-01-10 23:31:23 +0000482
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200483 /* Also checks keybits */
484 if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200485 goto exit;
Paul Bakker38119b12009-01-10 23:31:23 +0000486
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200487 ctx->nr = cty.nr;
488 idx = ( ctx->nr == 4 );
489
490 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000491 SK = cty.rk + 24 * 2 + 8 * idx * 2;
492
493 *RK++ = *SK++;
494 *RK++ = *SK++;
495 *RK++ = *SK++;
496 *RK++ = *SK++;
497
Paul Bakker66d5d072014-06-17 16:39:18 +0200498 for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 )
Paul Bakker38119b12009-01-10 23:31:23 +0000499 {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000500 *RK++ = *SK++;
501 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000502 }
503
504 SK -= 2;
505
506 *RK++ = *SK++;
507 *RK++ = *SK++;
508 *RK++ = *SK++;
509 *RK++ = *SK++;
510
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200511exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_camellia_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000513
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200514 return( ret );
Paul Bakker38119b12009-01-10 23:31:23 +0000515}
516
517/*
518 * Camellia-ECB block encryption/decryption
519 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
Paul Bakker38119b12009-01-10 23:31:23 +0000521 int mode,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000522 const unsigned char input[16],
Paul Bakker38119b12009-01-10 23:31:23 +0000523 unsigned char output[16] )
524{
Paul Bakker026c03b2009-03-28 17:53:03 +0000525 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000526 uint32_t *RK, X[4];
Paul Bakker38119b12009-01-10 23:31:23 +0000527
Paul Bakkerc2547b02009-07-20 20:40:52 +0000528 ( (void) mode );
529
Paul Bakker38119b12009-01-10 23:31:23 +0000530 NR = ctx->nr;
531 RK = ctx->rk;
532
Paul Bakker5c2364c2012-10-01 14:41:15 +0000533 GET_UINT32_BE( X[0], input, 0 );
534 GET_UINT32_BE( X[1], input, 4 );
535 GET_UINT32_BE( X[2], input, 8 );
536 GET_UINT32_BE( X[3], input, 12 );
Paul Bakker38119b12009-01-10 23:31:23 +0000537
538 X[0] ^= *RK++;
539 X[1] ^= *RK++;
540 X[2] ^= *RK++;
541 X[3] ^= *RK++;
542
Paul Bakker66d5d072014-06-17 16:39:18 +0200543 while( NR ) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000544 --NR;
Paul Bakker66d5d072014-06-17 16:39:18 +0200545 camellia_feistel( X, RK, X + 2 );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000546 RK += 2;
Paul Bakker66d5d072014-06-17 16:39:18 +0200547 camellia_feistel( X + 2, RK, X );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000548 RK += 2;
Paul Bakker66d5d072014-06-17 16:39:18 +0200549 camellia_feistel( X, RK, X + 2 );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000550 RK += 2;
Paul Bakker66d5d072014-06-17 16:39:18 +0200551 camellia_feistel( X + 2, RK, X );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000552 RK += 2;
Paul Bakker66d5d072014-06-17 16:39:18 +0200553 camellia_feistel( X, RK, X + 2 );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000554 RK += 2;
Paul Bakker66d5d072014-06-17 16:39:18 +0200555 camellia_feistel( X + 2, RK, X );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000556 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000557
Paul Bakker66d5d072014-06-17 16:39:18 +0200558 if( NR ) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000559 FL(X[0], X[1], RK[0], RK[1]);
560 RK += 2;
561 FLInv(X[2], X[3], RK[0], RK[1]);
562 RK += 2;
563 }
Paul Bakker38119b12009-01-10 23:31:23 +0000564 }
565
566 X[2] ^= *RK++;
567 X[3] ^= *RK++;
568 X[0] ^= *RK++;
569 X[1] ^= *RK++;
570
Paul Bakker5c2364c2012-10-01 14:41:15 +0000571 PUT_UINT32_BE( X[2], output, 0 );
572 PUT_UINT32_BE( X[3], output, 4 );
573 PUT_UINT32_BE( X[0], output, 8 );
574 PUT_UINT32_BE( X[1], output, 12 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000575
576 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000577}
578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000580/*
581 * Camellia-CBC buffer encryption/decryption
582 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
Paul Bakker38119b12009-01-10 23:31:23 +0000584 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000585 size_t length,
Paul Bakker38119b12009-01-10 23:31:23 +0000586 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000587 const unsigned char *input,
Paul Bakker38119b12009-01-10 23:31:23 +0000588 unsigned char *output )
589{
590 int i;
591 unsigned char temp[16];
592
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000593 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000595
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 if( mode == MBEDTLS_CAMELLIA_DECRYPT )
Paul Bakker38119b12009-01-10 23:31:23 +0000597 {
598 while( length > 0 )
599 {
600 memcpy( temp, input, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 mbedtls_camellia_crypt_ecb( ctx, mode, input, output );
Paul Bakker38119b12009-01-10 23:31:23 +0000602
603 for( i = 0; i < 16; i++ )
604 output[i] = (unsigned char)( output[i] ^ iv[i] );
605
606 memcpy( iv, temp, 16 );
607
608 input += 16;
609 output += 16;
610 length -= 16;
611 }
612 }
613 else
614 {
615 while( length > 0 )
616 {
617 for( i = 0; i < 16; i++ )
618 output[i] = (unsigned char)( input[i] ^ iv[i] );
619
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_camellia_crypt_ecb( ctx, mode, output, output );
Paul Bakker38119b12009-01-10 23:31:23 +0000621 memcpy( iv, output, 16 );
622
623 input += 16;
624 output += 16;
625 length -= 16;
626 }
627 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000628
629 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000630}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker38119b12009-01-10 23:31:23 +0000634/*
635 * Camellia-CFB128 buffer encryption/decryption
636 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
Paul Bakker38119b12009-01-10 23:31:23 +0000638 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000639 size_t length,
Paul Bakker1ef71df2011-06-09 14:14:58 +0000640 size_t *iv_off,
Paul Bakker38119b12009-01-10 23:31:23 +0000641 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000642 const unsigned char *input,
Paul Bakker38119b12009-01-10 23:31:23 +0000643 unsigned char *output )
644{
Paul Bakker1ef71df2011-06-09 14:14:58 +0000645 int c;
646 size_t n = *iv_off;
Paul Bakker38119b12009-01-10 23:31:23 +0000647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 if( mode == MBEDTLS_CAMELLIA_DECRYPT )
Paul Bakker38119b12009-01-10 23:31:23 +0000649 {
650 while( length-- )
651 {
652 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
Paul Bakker38119b12009-01-10 23:31:23 +0000654
655 c = *input++;
656 *output++ = (unsigned char)( c ^ iv[n] );
657 iv[n] = (unsigned char) c;
658
Paul Bakker66d5d072014-06-17 16:39:18 +0200659 n = ( n + 1 ) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000660 }
661 }
662 else
663 {
664 while( length-- )
665 {
666 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
Paul Bakker38119b12009-01-10 23:31:23 +0000668
669 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
670
Paul Bakker66d5d072014-06-17 16:39:18 +0200671 n = ( n + 1 ) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000672 }
673 }
674
675 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000676
677 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000678}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000680
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000682/*
683 * Camellia-CTR buffer encryption/decryption
684 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
Paul Bakker1ef71df2011-06-09 14:14:58 +0000686 size_t length,
687 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000688 unsigned char nonce_counter[16],
689 unsigned char stream_block[16],
690 const unsigned char *input,
691 unsigned char *output )
692{
Paul Bakker369e14b2012-04-18 14:16:09 +0000693 int c, i;
Paul Bakker1ef71df2011-06-09 14:14:58 +0000694 size_t n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000695
696 while( length-- )
697 {
698 if( n == 0 ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200700 stream_block );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000701
Paul Bakker369e14b2012-04-18 14:16:09 +0000702 for( i = 16; i > 0; i-- )
703 if( ++nonce_counter[i - 1] != 0 )
704 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000705 }
706 c = *input++;
707 *output++ = (unsigned char)( c ^ stream_block[n] );
708
Paul Bakker66d5d072014-06-17 16:39:18 +0200709 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000710 }
711
712 *nc_off = n;
713
714 return( 0 );
715}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716#endif /* MBEDTLS_CIPHER_MODE_CTR */
717#endif /* !MBEDTLS_CAMELLIA_ALT */
Paul Bakker38119b12009-01-10 23:31:23 +0000718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000720
Paul Bakker38119b12009-01-10 23:31:23 +0000721/*
722 * Camellia test vectors from:
723 *
724 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
725 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
726 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000727 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000728 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000729#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000730
731static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
732{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000733 {
734 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
735 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200736 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
738 },
739 {
740 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
741 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
742 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200743 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
746 },
747 {
748 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
749 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
750 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
751 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200752 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
756 },
Paul Bakker38119b12009-01-10 23:31:23 +0000757};
758
759static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
760{
761 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
762 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200763 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
765};
766
767static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
768{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000769 {
770 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
771 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
772 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
773 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
774 },
775 {
776 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
777 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
778 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
779 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
780 },
781 {
782 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
783 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
784 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
785 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
786 }
Paul Bakker38119b12009-01-10 23:31:23 +0000787};
788
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000790#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000791
792static const unsigned char camellia_test_cbc_key[3][32] =
793{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000794 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
795 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
796 ,
797 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
798 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
799 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
800 ,
801 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
802 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
803 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
804 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000805};
806
807static const unsigned char camellia_test_cbc_iv[16] =
808
809 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
810 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
811;
812
813static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
814{
815 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
816 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
817 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
818 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
819 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
820 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
821
822};
823
824static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
825{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000826 {
827 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
828 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
829 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
830 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
831 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
832 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
833 },
834 {
835 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
836 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
837 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
838 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
839 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
840 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
841 },
842 {
843 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
844 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
845 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
846 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
847 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
848 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
849 }
Paul Bakker38119b12009-01-10 23:31:23 +0000850};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000852
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000854/*
855 * Camellia-CTR test vectors from:
856 *
857 * http://www.faqs.org/rfcs/rfc5528.html
858 */
859
860static const unsigned char camellia_test_ctr_key[3][16] =
861{
862 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
863 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
864 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
865 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
866 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
867 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
868};
869
870static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
871{
872 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
873 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
874 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
875 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
876 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
877 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
878};
879
880static const unsigned char camellia_test_ctr_pt[3][48] =
881{
882 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
883 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
884
885 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
886 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
887 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
888 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
889
890 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
891 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
892 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
893 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
894 0x20, 0x21, 0x22, 0x23 }
895};
896
897static const unsigned char camellia_test_ctr_ct[3][48] =
898{
899 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
900 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
901 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
902 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
903 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
904 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
905 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
906 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
907 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
908 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
909 0xDF, 0x50, 0x86, 0x96 }
910};
911
912static const int camellia_test_ctr_len[3] =
913 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000915
916/*
917 * Checkup routine
918 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919int mbedtls_camellia_self_test( int verbose )
Paul Bakker38119b12009-01-10 23:31:23 +0000920{
Paul Bakker026c03b2009-03-28 17:53:03 +0000921 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000922 unsigned char key[32];
923 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000924 unsigned char src[16];
925 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000927 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200928#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000930 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000931 unsigned char nonce_counter[16];
932 unsigned char stream_block[16];
933#endif
934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000936
937 memset( key, 0, 32 );
938
Paul Bakker66d5d072014-06-17 16:39:18 +0200939 for( j = 0; j < 6; j++ ) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000940 u = j >> 1;
941 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000942
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000943 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
945 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakker38119b12009-01-10 23:31:23 +0000946
Paul Bakker66d5d072014-06-17 16:39:18 +0200947 for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) {
948 memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u );
Paul Bakker38119b12009-01-10 23:31:23 +0000949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
951 mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
Paul Bakker66d5d072014-06-17 16:39:18 +0200952 memcpy( src, camellia_test_ecb_cipher[u][i], 16 );
953 memcpy( dst, camellia_test_ecb_plain[i], 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
955 mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
Paul Bakker66d5d072014-06-17 16:39:18 +0200956 memcpy( src, camellia_test_ecb_plain[i], 16 );
957 memcpy( dst, camellia_test_ecb_cipher[u][i], 16 );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000958 }
Paul Bakker38119b12009-01-10 23:31:23 +0000959
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_camellia_crypt_ecb( &ctx, v, src, buf );
Paul Bakker38119b12009-01-10 23:31:23 +0000961
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000962 if( memcmp( buf, dst, 16 ) != 0 )
963 {
964 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_printf( "failed\n" );
Paul Bakker38119b12009-01-10 23:31:23 +0000966
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000967 return( 1 );
968 }
969 }
Paul Bakker38119b12009-01-10 23:31:23 +0000970
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000971 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 mbedtls_printf( "passed\n" );
Paul Bakker38119b12009-01-10 23:31:23 +0000973 }
974
975 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_printf( "\n" );
Paul Bakker38119b12009-01-10 23:31:23 +0000977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000979 /*
980 * CBC mode
981 */
982 for( j = 0; j < 6; j++ )
983 {
984 u = j >> 1;
985 v = j & 1;
986
987 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
989 ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
Paul Bakker38119b12009-01-10 23:31:23 +0000990
Janos Follath98e28a72016-05-31 14:03:54 +0100991 memcpy( src, camellia_test_cbc_iv, 16 );
992 memcpy( dst, camellia_test_cbc_iv, 16 );
993 memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
Paul Bakker38119b12009-01-10 23:31:23 +0000994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
Janos Follath98e28a72016-05-31 14:03:54 +0100996 mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
997 } else {
998 mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000999 }
Paul Bakker38119b12009-01-10 23:31:23 +00001000
Janos Follath98e28a72016-05-31 14:03:54 +01001001 for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
Paul Bakker38119b12009-01-10 23:31:23 +00001002
Janos Follath98e28a72016-05-31 14:03:54 +01001003 if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
1004 memcpy( iv , src, 16 );
1005 memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
1006 memcpy( dst, camellia_test_cbc_plain[i], 16 );
1007 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
1008 memcpy( iv , dst, 16 );
1009 memcpy( src, camellia_test_cbc_plain[i], 16 );
1010 memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
1011 }
Paul Bakker38119b12009-01-10 23:31:23 +00001012
Janos Follath98e28a72016-05-31 14:03:54 +01001013 mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
1014
1015 if( memcmp( buf, dst, 16 ) != 0 )
1016 {
1017 if( verbose != 0 )
1018 mbedtls_printf( "failed\n" );
1019
1020 return( 1 );
1021 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +00001022 }
Paul Bakker38119b12009-01-10 23:31:23 +00001023
1024 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 mbedtls_printf( "passed\n" );
Paul Bakker38119b12009-01-10 23:31:23 +00001026 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +00001028
1029 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 mbedtls_printf( "\n" );
Paul Bakker38119b12009-01-10 23:31:23 +00001031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001033 /*
1034 * CTR mode
1035 */
1036 for( i = 0; i < 6; i++ )
1037 {
1038 u = i >> 1;
1039 v = i & 1;
1040
1041 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042 mbedtls_printf( " CAMELLIA-CTR-128 (%s): ",
1043 ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001044
1045 memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 );
1046 memcpy( key, camellia_test_ctr_key[u], 16 );
1047
1048 offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 mbedtls_camellia_setkey_enc( &ctx, key, 128 );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051 if( v == MBEDTLS_CAMELLIA_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001052 {
1053 len = camellia_test_ctr_len[u];
1054 memcpy( buf, camellia_test_ctr_ct[u], len );
1055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001057 buf, buf );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001058
1059 if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 )
1060 {
1061 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 mbedtls_printf( "failed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001063
1064 return( 1 );
1065 }
1066 }
1067 else
1068 {
1069 len = camellia_test_ctr_len[u];
1070 memcpy( buf, camellia_test_ctr_pt[u], len );
1071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072 mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001073 buf, buf );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001074
1075 if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 )
1076 {
1077 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 mbedtls_printf( "failed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001079
1080 return( 1 );
1081 }
1082 }
1083
1084 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001086 }
1087
1088 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089 mbedtls_printf( "\n" );
1090#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001091
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001092 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +00001093}
1094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001095#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097#endif /* MBEDTLS_CAMELLIA_C */