1c2c66affSColin Finck /*
2c2c66affSColin Finck * Camellia implementation
3c2c66affSColin Finck *
4218e2596SThomas Faber * Copyright The Mbed TLS Contributors
5e57126f5SThomas Faber * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6e57126f5SThomas Faber *
7e57126f5SThomas Faber * This file is provided under the Apache License 2.0, or the
8e57126f5SThomas Faber * GNU General Public License v2.0 or later.
9e57126f5SThomas Faber *
10e57126f5SThomas Faber * **********
11e57126f5SThomas Faber * Apache License 2.0:
12e57126f5SThomas Faber *
13e57126f5SThomas Faber * Licensed under the Apache License, Version 2.0 (the "License"); you may
14e57126f5SThomas Faber * not use this file except in compliance with the License.
15e57126f5SThomas Faber * You may obtain a copy of the License at
16e57126f5SThomas Faber *
17e57126f5SThomas Faber * http://www.apache.org/licenses/LICENSE-2.0
18e57126f5SThomas Faber *
19e57126f5SThomas Faber * Unless required by applicable law or agreed to in writing, software
20e57126f5SThomas Faber * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21e57126f5SThomas Faber * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22e57126f5SThomas Faber * See the License for the specific language governing permissions and
23e57126f5SThomas Faber * limitations under the License.
24e57126f5SThomas Faber *
25e57126f5SThomas Faber * **********
26e57126f5SThomas Faber *
27e57126f5SThomas Faber * **********
28e57126f5SThomas Faber * GNU General Public License v2.0 or later:
29c2c66affSColin Finck *
30c2c66affSColin Finck * This program is free software; you can redistribute it and/or modify
31c2c66affSColin Finck * it under the terms of the GNU General Public License as published by
32c2c66affSColin Finck * the Free Software Foundation; either version 2 of the License, or
33c2c66affSColin Finck * (at your option) any later version.
34c2c66affSColin Finck *
35c2c66affSColin Finck * This program is distributed in the hope that it will be useful,
36c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
37c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38c2c66affSColin Finck * GNU General Public License for more details.
39c2c66affSColin Finck *
40c2c66affSColin Finck * You should have received a copy of the GNU General Public License along
41c2c66affSColin Finck * with this program; if not, write to the Free Software Foundation, Inc.,
42c2c66affSColin Finck * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43c2c66affSColin Finck *
44e57126f5SThomas Faber * **********
45c2c66affSColin Finck */
46c2c66affSColin Finck /*
47c2c66affSColin Finck * The Camellia block cipher was designed by NTT and Mitsubishi Electric
48c2c66affSColin Finck * Corporation.
49c2c66affSColin Finck *
50c2c66affSColin Finck * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
51c2c66affSColin Finck */
52c2c66affSColin Finck
53c2c66affSColin Finck #if !defined(MBEDTLS_CONFIG_FILE)
54c2c66affSColin Finck #include "mbedtls/config.h"
55c2c66affSColin Finck #else
56c2c66affSColin Finck #include MBEDTLS_CONFIG_FILE
57c2c66affSColin Finck #endif
58c2c66affSColin Finck
59c2c66affSColin Finck #if defined(MBEDTLS_CAMELLIA_C)
60c2c66affSColin Finck
61c2c66affSColin Finck #include "mbedtls/camellia.h"
62cbda039fSThomas Faber #include "mbedtls/platform_util.h"
63c2c66affSColin Finck
64c2c66affSColin Finck #include <string.h>
65c2c66affSColin Finck
66c2c66affSColin Finck #if defined(MBEDTLS_SELF_TEST)
67c2c66affSColin Finck #if defined(MBEDTLS_PLATFORM_C)
68c2c66affSColin Finck #include "mbedtls/platform.h"
69c2c66affSColin Finck #else
70c2c66affSColin Finck #include <stdio.h>
71c2c66affSColin Finck #define mbedtls_printf printf
72c2c66affSColin Finck #endif /* MBEDTLS_PLATFORM_C */
73c2c66affSColin Finck #endif /* MBEDTLS_SELF_TEST */
74c2c66affSColin Finck
75c2c66affSColin Finck #if !defined(MBEDTLS_CAMELLIA_ALT)
76c2c66affSColin Finck
77cbda039fSThomas Faber /* Parameter validation macros */
78cbda039fSThomas Faber #define CAMELLIA_VALIDATE_RET( cond ) \
79cbda039fSThomas Faber MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA )
80cbda039fSThomas Faber #define CAMELLIA_VALIDATE( cond ) \
81cbda039fSThomas Faber MBEDTLS_INTERNAL_VALIDATE( cond )
82c2c66affSColin Finck
83c2c66affSColin Finck /*
84c2c66affSColin Finck * 32-bit integer manipulation macros (big endian)
85c2c66affSColin Finck */
86c2c66affSColin Finck #ifndef GET_UINT32_BE
87c2c66affSColin Finck #define GET_UINT32_BE(n,b,i) \
88c2c66affSColin Finck { \
89c2c66affSColin Finck (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
90c2c66affSColin Finck | ( (uint32_t) (b)[(i) + 1] << 16 ) \
91c2c66affSColin Finck | ( (uint32_t) (b)[(i) + 2] << 8 ) \
92c2c66affSColin Finck | ( (uint32_t) (b)[(i) + 3] ); \
93c2c66affSColin Finck }
94c2c66affSColin Finck #endif
95c2c66affSColin Finck
96c2c66affSColin Finck #ifndef PUT_UINT32_BE
97c2c66affSColin Finck #define PUT_UINT32_BE(n,b,i) \
98c2c66affSColin Finck { \
99c2c66affSColin Finck (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
100c2c66affSColin Finck (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
101c2c66affSColin Finck (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
102c2c66affSColin Finck (b)[(i) + 3] = (unsigned char) ( (n) ); \
103c2c66affSColin Finck }
104c2c66affSColin Finck #endif
105c2c66affSColin Finck
106c2c66affSColin Finck static const unsigned char SIGMA_CHARS[6][8] =
107c2c66affSColin Finck {
108c2c66affSColin Finck { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
109c2c66affSColin Finck { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
110c2c66affSColin Finck { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
111c2c66affSColin Finck { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
112c2c66affSColin Finck { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
113c2c66affSColin Finck { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
114c2c66affSColin Finck };
115c2c66affSColin Finck
116c2c66affSColin Finck #if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
117c2c66affSColin Finck
118c2c66affSColin Finck static const unsigned char FSb[256] =
119c2c66affSColin Finck {
120c2c66affSColin Finck 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
121c2c66affSColin Finck 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
122c2c66affSColin Finck 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
123c2c66affSColin Finck 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
124c2c66affSColin Finck 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
125c2c66affSColin Finck 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
126c2c66affSColin Finck 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
127c2c66affSColin Finck 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
128c2c66affSColin Finck 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
129c2c66affSColin Finck 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
130c2c66affSColin Finck 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
131c2c66affSColin Finck 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
132c2c66affSColin Finck 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
133c2c66affSColin Finck 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
134c2c66affSColin Finck 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
135c2c66affSColin Finck 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
136c2c66affSColin Finck };
137c2c66affSColin Finck
138c2c66affSColin Finck #define SBOX1(n) FSb[(n)]
139c2c66affSColin Finck #define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
140c2c66affSColin Finck #define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
141c2c66affSColin Finck #define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
142c2c66affSColin Finck
143c2c66affSColin Finck #else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
144c2c66affSColin Finck
145c2c66affSColin Finck static const unsigned char FSb[256] =
146c2c66affSColin Finck {
147c2c66affSColin Finck 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
148c2c66affSColin Finck 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
149c2c66affSColin Finck 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
150c2c66affSColin Finck 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
151c2c66affSColin Finck 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
152c2c66affSColin Finck 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
153c2c66affSColin Finck 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
154c2c66affSColin Finck 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
155c2c66affSColin Finck 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
156c2c66affSColin Finck 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
157c2c66affSColin Finck 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
158c2c66affSColin Finck 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
159c2c66affSColin Finck 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
160c2c66affSColin Finck 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
161c2c66affSColin Finck 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
162c2c66affSColin Finck 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
163c2c66affSColin Finck };
164c2c66affSColin Finck
165c2c66affSColin Finck static const unsigned char FSb2[256] =
166c2c66affSColin Finck {
167c2c66affSColin Finck 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
168c2c66affSColin Finck 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
169c2c66affSColin Finck 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
170c2c66affSColin Finck 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
171c2c66affSColin Finck 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
172c2c66affSColin Finck 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
173c2c66affSColin Finck 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
174c2c66affSColin Finck 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
175c2c66affSColin Finck 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
176c2c66affSColin Finck 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
177c2c66affSColin Finck 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
178c2c66affSColin Finck 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
179c2c66affSColin Finck 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
180c2c66affSColin Finck 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
181c2c66affSColin Finck 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
182c2c66affSColin Finck 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
183c2c66affSColin Finck };
184c2c66affSColin Finck
185c2c66affSColin Finck static const unsigned char FSb3[256] =
186c2c66affSColin Finck {
187c2c66affSColin Finck 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
188c2c66affSColin Finck 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
189c2c66affSColin Finck 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
190c2c66affSColin Finck 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
191c2c66affSColin Finck 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
192c2c66affSColin Finck 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
193c2c66affSColin Finck 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
194c2c66affSColin Finck 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
195c2c66affSColin Finck 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
196c2c66affSColin Finck 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
197c2c66affSColin Finck 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
198c2c66affSColin Finck 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
199c2c66affSColin Finck 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
200c2c66affSColin Finck 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
201c2c66affSColin Finck 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
202c2c66affSColin Finck 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
203c2c66affSColin Finck };
204c2c66affSColin Finck
205c2c66affSColin Finck static const unsigned char FSb4[256] =
206c2c66affSColin Finck {
207c2c66affSColin Finck 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
208c2c66affSColin Finck 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
209c2c66affSColin Finck 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
210c2c66affSColin Finck 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
211c2c66affSColin Finck 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
212c2c66affSColin Finck 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
213c2c66affSColin Finck 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
214c2c66affSColin Finck 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
215c2c66affSColin Finck 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
216c2c66affSColin Finck 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
217c2c66affSColin Finck 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
218c2c66affSColin Finck 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
219c2c66affSColin Finck 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
220c2c66affSColin Finck 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
221c2c66affSColin Finck 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
222c2c66affSColin Finck 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
223c2c66affSColin Finck };
224c2c66affSColin Finck
225c2c66affSColin Finck #define SBOX1(n) FSb[(n)]
226c2c66affSColin Finck #define SBOX2(n) FSb2[(n)]
227c2c66affSColin Finck #define SBOX3(n) FSb3[(n)]
228c2c66affSColin Finck #define SBOX4(n) FSb4[(n)]
229c2c66affSColin Finck
230c2c66affSColin Finck #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
231c2c66affSColin Finck
232c2c66affSColin Finck static const unsigned char shifts[2][4][4] =
233c2c66affSColin Finck {
234c2c66affSColin Finck {
235c2c66affSColin Finck { 1, 1, 1, 1 }, /* KL */
236c2c66affSColin Finck { 0, 0, 0, 0 }, /* KR */
237c2c66affSColin Finck { 1, 1, 1, 1 }, /* KA */
238c2c66affSColin Finck { 0, 0, 0, 0 } /* KB */
239c2c66affSColin Finck },
240c2c66affSColin Finck {
241c2c66affSColin Finck { 1, 0, 1, 1 }, /* KL */
242c2c66affSColin Finck { 1, 1, 0, 1 }, /* KR */
243c2c66affSColin Finck { 1, 1, 1, 0 }, /* KA */
244c2c66affSColin Finck { 1, 1, 0, 1 } /* KB */
245c2c66affSColin Finck }
246c2c66affSColin Finck };
247c2c66affSColin Finck
248c2c66affSColin Finck static const signed char indexes[2][4][20] =
249c2c66affSColin Finck {
250c2c66affSColin Finck {
251c2c66affSColin Finck { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
252c2c66affSColin Finck 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
253c2c66affSColin Finck { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
254c2c66affSColin Finck -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
255c2c66affSColin Finck { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
256c2c66affSColin Finck 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
257c2c66affSColin Finck { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
258c2c66affSColin Finck -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
259c2c66affSColin Finck },
260c2c66affSColin Finck {
261c2c66affSColin Finck { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
262c2c66affSColin Finck -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
263c2c66affSColin Finck { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
264c2c66affSColin Finck 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
265c2c66affSColin Finck { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
266c2c66affSColin Finck 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
267c2c66affSColin Finck { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
268c2c66affSColin Finck 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
269c2c66affSColin Finck }
270c2c66affSColin Finck };
271c2c66affSColin Finck
272c2c66affSColin Finck static const signed char transposes[2][20] =
273c2c66affSColin Finck {
274c2c66affSColin Finck {
275c2c66affSColin Finck 21, 22, 23, 20,
276c2c66affSColin Finck -1, -1, -1, -1,
277c2c66affSColin Finck 18, 19, 16, 17,
278c2c66affSColin Finck 11, 8, 9, 10,
279c2c66affSColin Finck 15, 12, 13, 14
280c2c66affSColin Finck },
281c2c66affSColin Finck {
282c2c66affSColin Finck 25, 26, 27, 24,
283c2c66affSColin Finck 29, 30, 31, 28,
284c2c66affSColin Finck 18, 19, 16, 17,
285c2c66affSColin Finck -1, -1, -1, -1,
286c2c66affSColin Finck -1, -1, -1, -1
287c2c66affSColin Finck }
288c2c66affSColin Finck };
289c2c66affSColin Finck
290c2c66affSColin Finck /* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
291c2c66affSColin Finck #define ROTL(DEST, SRC, SHIFT) \
292c2c66affSColin Finck { \
293c2c66affSColin Finck (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
294c2c66affSColin Finck (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
295c2c66affSColin Finck (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
296c2c66affSColin Finck (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
297c2c66affSColin Finck }
298c2c66affSColin Finck
299c2c66affSColin Finck #define FL(XL, XR, KL, KR) \
300c2c66affSColin Finck { \
301c2c66affSColin Finck (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \
302c2c66affSColin Finck (XL) = ((XR) | (KR)) ^ (XL); \
303c2c66affSColin Finck }
304c2c66affSColin Finck
305c2c66affSColin Finck #define FLInv(YL, YR, KL, KR) \
306c2c66affSColin Finck { \
307c2c66affSColin Finck (YL) = ((YR) | (KR)) ^ (YL); \
308c2c66affSColin Finck (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \
309c2c66affSColin Finck }
310c2c66affSColin Finck
311c2c66affSColin Finck #define SHIFT_AND_PLACE(INDEX, OFFSET) \
312c2c66affSColin Finck { \
313c2c66affSColin Finck TK[0] = KC[(OFFSET) * 4 + 0]; \
314c2c66affSColin Finck TK[1] = KC[(OFFSET) * 4 + 1]; \
315c2c66affSColin Finck TK[2] = KC[(OFFSET) * 4 + 2]; \
316c2c66affSColin Finck TK[3] = KC[(OFFSET) * 4 + 3]; \
317c2c66affSColin Finck \
318c2c66affSColin Finck for( i = 1; i <= 4; i++ ) \
319c2c66affSColin Finck if( shifts[(INDEX)][(OFFSET)][i -1] ) \
320c2c66affSColin Finck ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \
321c2c66affSColin Finck \
322c2c66affSColin Finck for( i = 0; i < 20; i++ ) \
323c2c66affSColin Finck if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \
324c2c66affSColin Finck RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \
325c2c66affSColin Finck } \
326c2c66affSColin Finck }
327c2c66affSColin Finck
camellia_feistel(const uint32_t x[2],const uint32_t k[2],uint32_t z[2])328c2c66affSColin Finck static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
329c2c66affSColin Finck uint32_t z[2])
330c2c66affSColin Finck {
331c2c66affSColin Finck uint32_t I0, I1;
332c2c66affSColin Finck I0 = x[0] ^ k[0];
333c2c66affSColin Finck I1 = x[1] ^ k[1];
334c2c66affSColin Finck
335c2c66affSColin Finck I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
336c2c66affSColin Finck ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
337c2c66affSColin Finck ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) |
338c2c66affSColin Finck ((uint32_t) SBOX4((I0 ) & 0xFF) );
339c2c66affSColin Finck I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
340c2c66affSColin Finck ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
341c2c66affSColin Finck ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) |
342c2c66affSColin Finck ((uint32_t) SBOX1((I1 ) & 0xFF) );
343c2c66affSColin Finck
344c2c66affSColin Finck I0 ^= (I1 << 8) | (I1 >> 24);
345c2c66affSColin Finck I1 ^= (I0 << 16) | (I0 >> 16);
346c2c66affSColin Finck I0 ^= (I1 >> 8) | (I1 << 24);
347c2c66affSColin Finck I1 ^= (I0 >> 8) | (I0 << 24);
348c2c66affSColin Finck
349c2c66affSColin Finck z[0] ^= I1;
350c2c66affSColin Finck z[1] ^= I0;
351c2c66affSColin Finck }
352c2c66affSColin Finck
mbedtls_camellia_init(mbedtls_camellia_context * ctx)353c2c66affSColin Finck void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
354c2c66affSColin Finck {
355cbda039fSThomas Faber CAMELLIA_VALIDATE( ctx != NULL );
356c2c66affSColin Finck memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
357c2c66affSColin Finck }
358c2c66affSColin Finck
mbedtls_camellia_free(mbedtls_camellia_context * ctx)359c2c66affSColin Finck void mbedtls_camellia_free( mbedtls_camellia_context *ctx )
360c2c66affSColin Finck {
361c2c66affSColin Finck if( ctx == NULL )
362c2c66affSColin Finck return;
363c2c66affSColin Finck
364cbda039fSThomas Faber mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
365c2c66affSColin Finck }
366c2c66affSColin Finck
367c2c66affSColin Finck /*
368c2c66affSColin Finck * Camellia key schedule (encryption)
369c2c66affSColin Finck */
mbedtls_camellia_setkey_enc(mbedtls_camellia_context * ctx,const unsigned char * key,unsigned int keybits)370cbda039fSThomas Faber int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
371cbda039fSThomas Faber const unsigned char *key,
372c2c66affSColin Finck unsigned int keybits )
373c2c66affSColin Finck {
374c2c66affSColin Finck int idx;
375c2c66affSColin Finck size_t i;
376c2c66affSColin Finck uint32_t *RK;
377c2c66affSColin Finck unsigned char t[64];
378c2c66affSColin Finck uint32_t SIGMA[6][2];
379c2c66affSColin Finck uint32_t KC[16];
380c2c66affSColin Finck uint32_t TK[20];
381c2c66affSColin Finck
382cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( ctx != NULL );
383cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( key != NULL );
384cbda039fSThomas Faber
385c2c66affSColin Finck RK = ctx->rk;
386c2c66affSColin Finck
387c2c66affSColin Finck memset( t, 0, 64 );
388c2c66affSColin Finck memset( RK, 0, sizeof(ctx->rk) );
389c2c66affSColin Finck
390c2c66affSColin Finck switch( keybits )
391c2c66affSColin Finck {
392c2c66affSColin Finck case 128: ctx->nr = 3; idx = 0; break;
393c2c66affSColin Finck case 192:
394c2c66affSColin Finck case 256: ctx->nr = 4; idx = 1; break;
395cbda039fSThomas Faber default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
396c2c66affSColin Finck }
397c2c66affSColin Finck
398c2c66affSColin Finck for( i = 0; i < keybits / 8; ++i )
399c2c66affSColin Finck t[i] = key[i];
400c2c66affSColin Finck
401c2c66affSColin Finck if( keybits == 192 ) {
402c2c66affSColin Finck for( i = 0; i < 8; i++ )
403c2c66affSColin Finck t[24 + i] = ~t[16 + i];
404c2c66affSColin Finck }
405c2c66affSColin Finck
406c2c66affSColin Finck /*
407c2c66affSColin Finck * Prepare SIGMA values
408c2c66affSColin Finck */
409c2c66affSColin Finck for( i = 0; i < 6; i++ ) {
410c2c66affSColin Finck GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
411c2c66affSColin Finck GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
412c2c66affSColin Finck }
413c2c66affSColin Finck
414c2c66affSColin Finck /*
415c2c66affSColin Finck * Key storage in KC
416c2c66affSColin Finck * Order: KL, KR, KA, KB
417c2c66affSColin Finck */
418c2c66affSColin Finck memset( KC, 0, sizeof(KC) );
419c2c66affSColin Finck
420c2c66affSColin Finck /* Store KL, KR */
421c2c66affSColin Finck for( i = 0; i < 8; i++ )
422c2c66affSColin Finck GET_UINT32_BE( KC[i], t, i * 4 );
423c2c66affSColin Finck
424c2c66affSColin Finck /* Generate KA */
425c2c66affSColin Finck for( i = 0; i < 4; ++i )
426c2c66affSColin Finck KC[8 + i] = KC[i] ^ KC[4 + i];
427c2c66affSColin Finck
428c2c66affSColin Finck camellia_feistel( KC + 8, SIGMA[0], KC + 10 );
429c2c66affSColin Finck camellia_feistel( KC + 10, SIGMA[1], KC + 8 );
430c2c66affSColin Finck
431c2c66affSColin Finck for( i = 0; i < 4; ++i )
432c2c66affSColin Finck KC[8 + i] ^= KC[i];
433c2c66affSColin Finck
434c2c66affSColin Finck camellia_feistel( KC + 8, SIGMA[2], KC + 10 );
435c2c66affSColin Finck camellia_feistel( KC + 10, SIGMA[3], KC + 8 );
436c2c66affSColin Finck
437c2c66affSColin Finck if( keybits > 128 ) {
438c2c66affSColin Finck /* Generate KB */
439c2c66affSColin Finck for( i = 0; i < 4; ++i )
440c2c66affSColin Finck KC[12 + i] = KC[4 + i] ^ KC[8 + i];
441c2c66affSColin Finck
442c2c66affSColin Finck camellia_feistel( KC + 12, SIGMA[4], KC + 14 );
443c2c66affSColin Finck camellia_feistel( KC + 14, SIGMA[5], KC + 12 );
444c2c66affSColin Finck }
445c2c66affSColin Finck
446c2c66affSColin Finck /*
447c2c66affSColin Finck * Generating subkeys
448c2c66affSColin Finck */
449c2c66affSColin Finck
450c2c66affSColin Finck /* Manipulating KL */
451c2c66affSColin Finck SHIFT_AND_PLACE( idx, 0 );
452c2c66affSColin Finck
453c2c66affSColin Finck /* Manipulating KR */
454c2c66affSColin Finck if( keybits > 128 ) {
455c2c66affSColin Finck SHIFT_AND_PLACE( idx, 1 );
456c2c66affSColin Finck }
457c2c66affSColin Finck
458c2c66affSColin Finck /* Manipulating KA */
459c2c66affSColin Finck SHIFT_AND_PLACE( idx, 2 );
460c2c66affSColin Finck
461c2c66affSColin Finck /* Manipulating KB */
462c2c66affSColin Finck if( keybits > 128 ) {
463c2c66affSColin Finck SHIFT_AND_PLACE( idx, 3 );
464c2c66affSColin Finck }
465c2c66affSColin Finck
466c2c66affSColin Finck /* Do transpositions */
467c2c66affSColin Finck for( i = 0; i < 20; i++ ) {
468c2c66affSColin Finck if( transposes[idx][i] != -1 ) {
469c2c66affSColin Finck RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
470c2c66affSColin Finck }
471c2c66affSColin Finck }
472c2c66affSColin Finck
473c2c66affSColin Finck return( 0 );
474c2c66affSColin Finck }
475c2c66affSColin Finck
476c2c66affSColin Finck /*
477c2c66affSColin Finck * Camellia key schedule (decryption)
478c2c66affSColin Finck */
mbedtls_camellia_setkey_dec(mbedtls_camellia_context * ctx,const unsigned char * key,unsigned int keybits)479cbda039fSThomas Faber int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
480cbda039fSThomas Faber const unsigned char *key,
481c2c66affSColin Finck unsigned int keybits )
482c2c66affSColin Finck {
483c2c66affSColin Finck int idx, ret;
484c2c66affSColin Finck size_t i;
485c2c66affSColin Finck mbedtls_camellia_context cty;
486c2c66affSColin Finck uint32_t *RK;
487c2c66affSColin Finck uint32_t *SK;
488cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( ctx != NULL );
489cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( key != NULL );
490c2c66affSColin Finck
491c2c66affSColin Finck mbedtls_camellia_init( &cty );
492c2c66affSColin Finck
493c2c66affSColin Finck /* Also checks keybits */
494c2c66affSColin Finck if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 )
495c2c66affSColin Finck goto exit;
496c2c66affSColin Finck
497c2c66affSColin Finck ctx->nr = cty.nr;
498c2c66affSColin Finck idx = ( ctx->nr == 4 );
499c2c66affSColin Finck
500c2c66affSColin Finck RK = ctx->rk;
501c2c66affSColin Finck SK = cty.rk + 24 * 2 + 8 * idx * 2;
502c2c66affSColin Finck
503c2c66affSColin Finck *RK++ = *SK++;
504c2c66affSColin Finck *RK++ = *SK++;
505c2c66affSColin Finck *RK++ = *SK++;
506c2c66affSColin Finck *RK++ = *SK++;
507c2c66affSColin Finck
508c2c66affSColin Finck for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 )
509c2c66affSColin Finck {
510c2c66affSColin Finck *RK++ = *SK++;
511c2c66affSColin Finck *RK++ = *SK++;
512c2c66affSColin Finck }
513c2c66affSColin Finck
514c2c66affSColin Finck SK -= 2;
515c2c66affSColin Finck
516c2c66affSColin Finck *RK++ = *SK++;
517c2c66affSColin Finck *RK++ = *SK++;
518c2c66affSColin Finck *RK++ = *SK++;
519c2c66affSColin Finck *RK++ = *SK++;
520c2c66affSColin Finck
521c2c66affSColin Finck exit:
522c2c66affSColin Finck mbedtls_camellia_free( &cty );
523c2c66affSColin Finck
524c2c66affSColin Finck return( ret );
525c2c66affSColin Finck }
526c2c66affSColin Finck
527c2c66affSColin Finck /*
528c2c66affSColin Finck * Camellia-ECB block encryption/decryption
529c2c66affSColin Finck */
mbedtls_camellia_crypt_ecb(mbedtls_camellia_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])530c2c66affSColin Finck int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
531c2c66affSColin Finck int mode,
532c2c66affSColin Finck const unsigned char input[16],
533c2c66affSColin Finck unsigned char output[16] )
534c2c66affSColin Finck {
535c2c66affSColin Finck int NR;
536c2c66affSColin Finck uint32_t *RK, X[4];
537cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( ctx != NULL );
538cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
539cbda039fSThomas Faber mode == MBEDTLS_CAMELLIA_DECRYPT );
540cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( input != NULL );
541cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( output != NULL );
542c2c66affSColin Finck
543c2c66affSColin Finck ( (void) mode );
544c2c66affSColin Finck
545c2c66affSColin Finck NR = ctx->nr;
546c2c66affSColin Finck RK = ctx->rk;
547c2c66affSColin Finck
548c2c66affSColin Finck GET_UINT32_BE( X[0], input, 0 );
549c2c66affSColin Finck GET_UINT32_BE( X[1], input, 4 );
550c2c66affSColin Finck GET_UINT32_BE( X[2], input, 8 );
551c2c66affSColin Finck GET_UINT32_BE( X[3], input, 12 );
552c2c66affSColin Finck
553c2c66affSColin Finck X[0] ^= *RK++;
554c2c66affSColin Finck X[1] ^= *RK++;
555c2c66affSColin Finck X[2] ^= *RK++;
556c2c66affSColin Finck X[3] ^= *RK++;
557c2c66affSColin Finck
558c2c66affSColin Finck while( NR ) {
559c2c66affSColin Finck --NR;
560c2c66affSColin Finck camellia_feistel( X, RK, X + 2 );
561c2c66affSColin Finck RK += 2;
562c2c66affSColin Finck camellia_feistel( X + 2, RK, X );
563c2c66affSColin Finck RK += 2;
564c2c66affSColin Finck camellia_feistel( X, RK, X + 2 );
565c2c66affSColin Finck RK += 2;
566c2c66affSColin Finck camellia_feistel( X + 2, RK, X );
567c2c66affSColin Finck RK += 2;
568c2c66affSColin Finck camellia_feistel( X, RK, X + 2 );
569c2c66affSColin Finck RK += 2;
570c2c66affSColin Finck camellia_feistel( X + 2, RK, X );
571c2c66affSColin Finck RK += 2;
572c2c66affSColin Finck
573c2c66affSColin Finck if( NR ) {
574c2c66affSColin Finck FL(X[0], X[1], RK[0], RK[1]);
575c2c66affSColin Finck RK += 2;
576c2c66affSColin Finck FLInv(X[2], X[3], RK[0], RK[1]);
577c2c66affSColin Finck RK += 2;
578c2c66affSColin Finck }
579c2c66affSColin Finck }
580c2c66affSColin Finck
581c2c66affSColin Finck X[2] ^= *RK++;
582c2c66affSColin Finck X[3] ^= *RK++;
583c2c66affSColin Finck X[0] ^= *RK++;
584c2c66affSColin Finck X[1] ^= *RK++;
585c2c66affSColin Finck
586c2c66affSColin Finck PUT_UINT32_BE( X[2], output, 0 );
587c2c66affSColin Finck PUT_UINT32_BE( X[3], output, 4 );
588c2c66affSColin Finck PUT_UINT32_BE( X[0], output, 8 );
589c2c66affSColin Finck PUT_UINT32_BE( X[1], output, 12 );
590c2c66affSColin Finck
591c2c66affSColin Finck return( 0 );
592c2c66affSColin Finck }
593c2c66affSColin Finck
594c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
595c2c66affSColin Finck /*
596c2c66affSColin Finck * Camellia-CBC buffer encryption/decryption
597c2c66affSColin Finck */
mbedtls_camellia_crypt_cbc(mbedtls_camellia_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)598c2c66affSColin Finck int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
599c2c66affSColin Finck int mode,
600c2c66affSColin Finck size_t length,
601c2c66affSColin Finck unsigned char iv[16],
602c2c66affSColin Finck const unsigned char *input,
603c2c66affSColin Finck unsigned char *output )
604c2c66affSColin Finck {
605c2c66affSColin Finck int i;
606c2c66affSColin Finck unsigned char temp[16];
607cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( ctx != NULL );
608cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
609cbda039fSThomas Faber mode == MBEDTLS_CAMELLIA_DECRYPT );
610cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( iv != NULL );
611cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
612cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
613c2c66affSColin Finck
614c2c66affSColin Finck if( length % 16 )
615c2c66affSColin Finck return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
616c2c66affSColin Finck
617c2c66affSColin Finck if( mode == MBEDTLS_CAMELLIA_DECRYPT )
618c2c66affSColin Finck {
619c2c66affSColin Finck while( length > 0 )
620c2c66affSColin Finck {
621c2c66affSColin Finck memcpy( temp, input, 16 );
622c2c66affSColin Finck mbedtls_camellia_crypt_ecb( ctx, mode, input, output );
623c2c66affSColin Finck
624c2c66affSColin Finck for( i = 0; i < 16; i++ )
625c2c66affSColin Finck output[i] = (unsigned char)( output[i] ^ iv[i] );
626c2c66affSColin Finck
627c2c66affSColin Finck memcpy( iv, temp, 16 );
628c2c66affSColin Finck
629c2c66affSColin Finck input += 16;
630c2c66affSColin Finck output += 16;
631c2c66affSColin Finck length -= 16;
632c2c66affSColin Finck }
633c2c66affSColin Finck }
634c2c66affSColin Finck else
635c2c66affSColin Finck {
636c2c66affSColin Finck while( length > 0 )
637c2c66affSColin Finck {
638c2c66affSColin Finck for( i = 0; i < 16; i++ )
639c2c66affSColin Finck output[i] = (unsigned char)( input[i] ^ iv[i] );
640c2c66affSColin Finck
641c2c66affSColin Finck mbedtls_camellia_crypt_ecb( ctx, mode, output, output );
642c2c66affSColin Finck memcpy( iv, output, 16 );
643c2c66affSColin Finck
644c2c66affSColin Finck input += 16;
645c2c66affSColin Finck output += 16;
646c2c66affSColin Finck length -= 16;
647c2c66affSColin Finck }
648c2c66affSColin Finck }
649c2c66affSColin Finck
650c2c66affSColin Finck return( 0 );
651c2c66affSColin Finck }
652c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
653c2c66affSColin Finck
654c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CFB)
655c2c66affSColin Finck /*
656c2c66affSColin Finck * Camellia-CFB128 buffer encryption/decryption
657c2c66affSColin Finck */
mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context * ctx,int mode,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)658c2c66affSColin Finck int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
659c2c66affSColin Finck int mode,
660c2c66affSColin Finck size_t length,
661c2c66affSColin Finck size_t *iv_off,
662c2c66affSColin Finck unsigned char iv[16],
663c2c66affSColin Finck const unsigned char *input,
664c2c66affSColin Finck unsigned char *output )
665c2c66affSColin Finck {
666c2c66affSColin Finck int c;
667cbda039fSThomas Faber size_t n;
668cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( ctx != NULL );
669cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
670cbda039fSThomas Faber mode == MBEDTLS_CAMELLIA_DECRYPT );
671cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( iv != NULL );
672cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( iv_off != NULL );
673cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
674cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
675cbda039fSThomas Faber
676cbda039fSThomas Faber n = *iv_off;
677cbda039fSThomas Faber if( n >= 16 )
678cbda039fSThomas Faber return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
679c2c66affSColin Finck
680c2c66affSColin Finck if( mode == MBEDTLS_CAMELLIA_DECRYPT )
681c2c66affSColin Finck {
682c2c66affSColin Finck while( length-- )
683c2c66affSColin Finck {
684c2c66affSColin Finck if( n == 0 )
685c2c66affSColin Finck mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
686c2c66affSColin Finck
687c2c66affSColin Finck c = *input++;
688c2c66affSColin Finck *output++ = (unsigned char)( c ^ iv[n] );
689c2c66affSColin Finck iv[n] = (unsigned char) c;
690c2c66affSColin Finck
691c2c66affSColin Finck n = ( n + 1 ) & 0x0F;
692c2c66affSColin Finck }
693c2c66affSColin Finck }
694c2c66affSColin Finck else
695c2c66affSColin Finck {
696c2c66affSColin Finck while( length-- )
697c2c66affSColin Finck {
698c2c66affSColin Finck if( n == 0 )
699c2c66affSColin Finck mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
700c2c66affSColin Finck
701c2c66affSColin Finck iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
702c2c66affSColin Finck
703c2c66affSColin Finck n = ( n + 1 ) & 0x0F;
704c2c66affSColin Finck }
705c2c66affSColin Finck }
706c2c66affSColin Finck
707c2c66affSColin Finck *iv_off = n;
708c2c66affSColin Finck
709c2c66affSColin Finck return( 0 );
710c2c66affSColin Finck }
711c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CFB */
712c2c66affSColin Finck
713c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CTR)
714c2c66affSColin Finck /*
715c2c66affSColin Finck * Camellia-CTR buffer encryption/decryption
716c2c66affSColin Finck */
mbedtls_camellia_crypt_ctr(mbedtls_camellia_context * ctx,size_t length,size_t * nc_off,unsigned char nonce_counter[16],unsigned char stream_block[16],const unsigned char * input,unsigned char * output)717c2c66affSColin Finck int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
718c2c66affSColin Finck size_t length,
719c2c66affSColin Finck size_t *nc_off,
720c2c66affSColin Finck unsigned char nonce_counter[16],
721c2c66affSColin Finck unsigned char stream_block[16],
722c2c66affSColin Finck const unsigned char *input,
723c2c66affSColin Finck unsigned char *output )
724c2c66affSColin Finck {
725c2c66affSColin Finck int c, i;
726cbda039fSThomas Faber size_t n;
727cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( ctx != NULL );
728cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( nonce_counter != NULL );
729cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( stream_block != NULL );
730cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( nc_off != NULL );
731cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( length == 0 || input != NULL );
732cbda039fSThomas Faber CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
733cbda039fSThomas Faber
734cbda039fSThomas Faber n = *nc_off;
735cbda039fSThomas Faber if( n >= 16 )
736cbda039fSThomas Faber return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
737c2c66affSColin Finck
738c2c66affSColin Finck while( length-- )
739c2c66affSColin Finck {
740c2c66affSColin Finck if( n == 0 ) {
741c2c66affSColin Finck mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
742c2c66affSColin Finck stream_block );
743c2c66affSColin Finck
744c2c66affSColin Finck for( i = 16; i > 0; i-- )
745c2c66affSColin Finck if( ++nonce_counter[i - 1] != 0 )
746c2c66affSColin Finck break;
747c2c66affSColin Finck }
748c2c66affSColin Finck c = *input++;
749c2c66affSColin Finck *output++ = (unsigned char)( c ^ stream_block[n] );
750c2c66affSColin Finck
751c2c66affSColin Finck n = ( n + 1 ) & 0x0F;
752c2c66affSColin Finck }
753c2c66affSColin Finck
754c2c66affSColin Finck *nc_off = n;
755c2c66affSColin Finck
756c2c66affSColin Finck return( 0 );
757c2c66affSColin Finck }
758c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CTR */
759c2c66affSColin Finck #endif /* !MBEDTLS_CAMELLIA_ALT */
760c2c66affSColin Finck
761c2c66affSColin Finck #if defined(MBEDTLS_SELF_TEST)
762c2c66affSColin Finck
763c2c66affSColin Finck /*
764c2c66affSColin Finck * Camellia test vectors from:
765c2c66affSColin Finck *
766c2c66affSColin Finck * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
767c2c66affSColin Finck * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
768c2c66affSColin Finck * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
769c2c66affSColin Finck * (For each bitlength: Key 0, Nr 39)
770c2c66affSColin Finck */
771c2c66affSColin Finck #define CAMELLIA_TESTS_ECB 2
772c2c66affSColin Finck
773c2c66affSColin Finck static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
774c2c66affSColin Finck {
775c2c66affSColin Finck {
776c2c66affSColin Finck { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
777c2c66affSColin Finck 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
778c2c66affSColin Finck { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
780c2c66affSColin Finck },
781c2c66affSColin Finck {
782c2c66affSColin Finck { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
783c2c66affSColin Finck 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
784c2c66affSColin Finck 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
785c2c66affSColin Finck { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
788c2c66affSColin Finck },
789c2c66affSColin Finck {
790c2c66affSColin Finck { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
791c2c66affSColin Finck 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
792c2c66affSColin Finck 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
793c2c66affSColin Finck 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
794c2c66affSColin Finck { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
798c2c66affSColin Finck },
799c2c66affSColin Finck };
800c2c66affSColin Finck
801c2c66affSColin Finck static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
802c2c66affSColin Finck {
803c2c66affSColin Finck { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
804c2c66affSColin Finck 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
805c2c66affSColin Finck { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
806c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
807c2c66affSColin Finck };
808c2c66affSColin Finck
809c2c66affSColin Finck static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
810c2c66affSColin Finck {
811c2c66affSColin Finck {
812c2c66affSColin Finck { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
813c2c66affSColin Finck 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
814c2c66affSColin Finck { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
815c2c66affSColin Finck 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
816c2c66affSColin Finck },
817c2c66affSColin Finck {
818c2c66affSColin Finck { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
819c2c66affSColin Finck 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
820c2c66affSColin Finck { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
821c2c66affSColin Finck 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
822c2c66affSColin Finck },
823c2c66affSColin Finck {
824c2c66affSColin Finck { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
825c2c66affSColin Finck 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
826c2c66affSColin Finck { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
827c2c66affSColin Finck 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
828c2c66affSColin Finck }
829c2c66affSColin Finck };
830c2c66affSColin Finck
831c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
832c2c66affSColin Finck #define CAMELLIA_TESTS_CBC 3
833c2c66affSColin Finck
834c2c66affSColin Finck static const unsigned char camellia_test_cbc_key[3][32] =
835c2c66affSColin Finck {
836c2c66affSColin Finck { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
837c2c66affSColin Finck 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
838c2c66affSColin Finck ,
839c2c66affSColin Finck { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
840c2c66affSColin Finck 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
841c2c66affSColin Finck 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
842c2c66affSColin Finck ,
843c2c66affSColin Finck { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
844c2c66affSColin Finck 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
845c2c66affSColin Finck 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
846c2c66affSColin Finck 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
847c2c66affSColin Finck };
848c2c66affSColin Finck
849c2c66affSColin Finck static const unsigned char camellia_test_cbc_iv[16] =
850c2c66affSColin Finck
851c2c66affSColin Finck { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
852c2c66affSColin Finck 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
853c2c66affSColin Finck ;
854c2c66affSColin Finck
855c2c66affSColin Finck static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
856c2c66affSColin Finck {
857c2c66affSColin Finck { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
858c2c66affSColin Finck 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
859c2c66affSColin Finck { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
860c2c66affSColin Finck 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
861c2c66affSColin Finck { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
862c2c66affSColin Finck 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
863c2c66affSColin Finck
864c2c66affSColin Finck };
865c2c66affSColin Finck
866c2c66affSColin Finck static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
867c2c66affSColin Finck {
868c2c66affSColin Finck {
869c2c66affSColin Finck { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
870c2c66affSColin Finck 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
871c2c66affSColin Finck { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
872c2c66affSColin Finck 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
873c2c66affSColin Finck { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
874c2c66affSColin Finck 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
875c2c66affSColin Finck },
876c2c66affSColin Finck {
877c2c66affSColin Finck { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
878c2c66affSColin Finck 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
879c2c66affSColin Finck { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
880c2c66affSColin Finck 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
881c2c66affSColin Finck { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
882c2c66affSColin Finck 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
883c2c66affSColin Finck },
884c2c66affSColin Finck {
885c2c66affSColin Finck { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
886c2c66affSColin Finck 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
887c2c66affSColin Finck { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
888c2c66affSColin Finck 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
889c2c66affSColin Finck { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
890c2c66affSColin Finck 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
891c2c66affSColin Finck }
892c2c66affSColin Finck };
893c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
894c2c66affSColin Finck
895c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CTR)
896c2c66affSColin Finck /*
897c2c66affSColin Finck * Camellia-CTR test vectors from:
898c2c66affSColin Finck *
899c2c66affSColin Finck * http://www.faqs.org/rfcs/rfc5528.html
900c2c66affSColin Finck */
901c2c66affSColin Finck
902c2c66affSColin Finck static const unsigned char camellia_test_ctr_key[3][16] =
903c2c66affSColin Finck {
904c2c66affSColin Finck { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
905c2c66affSColin Finck 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
906c2c66affSColin Finck { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
907c2c66affSColin Finck 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
908c2c66affSColin Finck { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
909c2c66affSColin Finck 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
910c2c66affSColin Finck };
911c2c66affSColin Finck
912c2c66affSColin Finck static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
913c2c66affSColin Finck {
914c2c66affSColin Finck { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
915c2c66affSColin Finck 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
916c2c66affSColin Finck { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
917c2c66affSColin Finck 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
918c2c66affSColin Finck { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
919c2c66affSColin Finck 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
920c2c66affSColin Finck };
921c2c66affSColin Finck
922c2c66affSColin Finck static const unsigned char camellia_test_ctr_pt[3][48] =
923c2c66affSColin Finck {
924c2c66affSColin Finck { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
925c2c66affSColin Finck 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
926c2c66affSColin Finck
927c2c66affSColin Finck { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
928c2c66affSColin Finck 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
929c2c66affSColin Finck 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
930c2c66affSColin Finck 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
931c2c66affSColin Finck
932c2c66affSColin Finck { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
933c2c66affSColin Finck 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
934c2c66affSColin Finck 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
935c2c66affSColin Finck 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
936c2c66affSColin Finck 0x20, 0x21, 0x22, 0x23 }
937c2c66affSColin Finck };
938c2c66affSColin Finck
939c2c66affSColin Finck static const unsigned char camellia_test_ctr_ct[3][48] =
940c2c66affSColin Finck {
941c2c66affSColin Finck { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
942c2c66affSColin Finck 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
943c2c66affSColin Finck { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
944c2c66affSColin Finck 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
945c2c66affSColin Finck 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
946c2c66affSColin Finck 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
947c2c66affSColin Finck { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
948c2c66affSColin Finck 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
949c2c66affSColin Finck 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
950c2c66affSColin Finck 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
951c2c66affSColin Finck 0xDF, 0x50, 0x86, 0x96 }
952c2c66affSColin Finck };
953c2c66affSColin Finck
954c2c66affSColin Finck static const int camellia_test_ctr_len[3] =
955c2c66affSColin Finck { 16, 32, 36 };
956c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CTR */
957c2c66affSColin Finck
958c2c66affSColin Finck /*
959c2c66affSColin Finck * Checkup routine
960c2c66affSColin Finck */
mbedtls_camellia_self_test(int verbose)961c2c66affSColin Finck int mbedtls_camellia_self_test( int verbose )
962c2c66affSColin Finck {
963c2c66affSColin Finck int i, j, u, v;
964c2c66affSColin Finck unsigned char key[32];
965c2c66affSColin Finck unsigned char buf[64];
966c2c66affSColin Finck unsigned char src[16];
967c2c66affSColin Finck unsigned char dst[16];
968c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
969c2c66affSColin Finck unsigned char iv[16];
970c2c66affSColin Finck #endif
971c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CTR)
972c2c66affSColin Finck size_t offset, len;
973c2c66affSColin Finck unsigned char nonce_counter[16];
974c2c66affSColin Finck unsigned char stream_block[16];
975c2c66affSColin Finck #endif
976*103a79ceSThomas Faber int ret = 1;
977c2c66affSColin Finck
978c2c66affSColin Finck mbedtls_camellia_context ctx;
979c2c66affSColin Finck
980*103a79ceSThomas Faber mbedtls_camellia_init( &ctx );
981c2c66affSColin Finck memset( key, 0, 32 );
982c2c66affSColin Finck
983c2c66affSColin Finck for( j = 0; j < 6; j++ ) {
984c2c66affSColin Finck u = j >> 1;
985c2c66affSColin Finck v = j & 1;
986c2c66affSColin Finck
987c2c66affSColin Finck if( verbose != 0 )
988c2c66affSColin Finck mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
989c2c66affSColin Finck (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
990c2c66affSColin Finck
991c2c66affSColin Finck for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) {
992c2c66affSColin Finck memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u );
993c2c66affSColin Finck
994c2c66affSColin Finck if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
995c2c66affSColin Finck mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
996c2c66affSColin Finck memcpy( src, camellia_test_ecb_cipher[u][i], 16 );
997c2c66affSColin Finck memcpy( dst, camellia_test_ecb_plain[i], 16 );
998c2c66affSColin Finck } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
999c2c66affSColin Finck mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
1000c2c66affSColin Finck memcpy( src, camellia_test_ecb_plain[i], 16 );
1001c2c66affSColin Finck memcpy( dst, camellia_test_ecb_cipher[u][i], 16 );
1002c2c66affSColin Finck }
1003c2c66affSColin Finck
1004c2c66affSColin Finck mbedtls_camellia_crypt_ecb( &ctx, v, src, buf );
1005c2c66affSColin Finck
1006c2c66affSColin Finck if( memcmp( buf, dst, 16 ) != 0 )
1007c2c66affSColin Finck {
1008c2c66affSColin Finck if( verbose != 0 )
1009c2c66affSColin Finck mbedtls_printf( "failed\n" );
1010*103a79ceSThomas Faber goto exit;
1011c2c66affSColin Finck }
1012c2c66affSColin Finck }
1013c2c66affSColin Finck
1014c2c66affSColin Finck if( verbose != 0 )
1015c2c66affSColin Finck mbedtls_printf( "passed\n" );
1016c2c66affSColin Finck }
1017c2c66affSColin Finck
1018c2c66affSColin Finck if( verbose != 0 )
1019c2c66affSColin Finck mbedtls_printf( "\n" );
1020c2c66affSColin Finck
1021c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
1022c2c66affSColin Finck /*
1023c2c66affSColin Finck * CBC mode
1024c2c66affSColin Finck */
1025c2c66affSColin Finck for( j = 0; j < 6; j++ )
1026c2c66affSColin Finck {
1027c2c66affSColin Finck u = j >> 1;
1028c2c66affSColin Finck v = j & 1;
1029c2c66affSColin Finck
1030c2c66affSColin Finck if( verbose != 0 )
1031c2c66affSColin Finck mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
1032c2c66affSColin Finck ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
1033c2c66affSColin Finck
1034c2c66affSColin Finck memcpy( src, camellia_test_cbc_iv, 16 );
1035c2c66affSColin Finck memcpy( dst, camellia_test_cbc_iv, 16 );
1036c2c66affSColin Finck memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
1037c2c66affSColin Finck
1038c2c66affSColin Finck if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
1039c2c66affSColin Finck mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
1040c2c66affSColin Finck } else {
1041c2c66affSColin Finck mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
1042c2c66affSColin Finck }
1043c2c66affSColin Finck
1044c2c66affSColin Finck for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
1045c2c66affSColin Finck
1046c2c66affSColin Finck if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
1047c2c66affSColin Finck memcpy( iv , src, 16 );
1048c2c66affSColin Finck memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
1049c2c66affSColin Finck memcpy( dst, camellia_test_cbc_plain[i], 16 );
1050c2c66affSColin Finck } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
1051c2c66affSColin Finck memcpy( iv , dst, 16 );
1052c2c66affSColin Finck memcpy( src, camellia_test_cbc_plain[i], 16 );
1053c2c66affSColin Finck memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
1054c2c66affSColin Finck }
1055c2c66affSColin Finck
1056c2c66affSColin Finck mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
1057c2c66affSColin Finck
1058c2c66affSColin Finck if( memcmp( buf, dst, 16 ) != 0 )
1059c2c66affSColin Finck {
1060c2c66affSColin Finck if( verbose != 0 )
1061c2c66affSColin Finck mbedtls_printf( "failed\n" );
1062*103a79ceSThomas Faber goto exit;
1063c2c66affSColin Finck }
1064c2c66affSColin Finck }
1065c2c66affSColin Finck
1066c2c66affSColin Finck if( verbose != 0 )
1067c2c66affSColin Finck mbedtls_printf( "passed\n" );
1068c2c66affSColin Finck }
1069c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
1070c2c66affSColin Finck
1071c2c66affSColin Finck if( verbose != 0 )
1072c2c66affSColin Finck mbedtls_printf( "\n" );
1073c2c66affSColin Finck
1074c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CTR)
1075c2c66affSColin Finck /*
1076c2c66affSColin Finck * CTR mode
1077c2c66affSColin Finck */
1078c2c66affSColin Finck for( i = 0; i < 6; i++ )
1079c2c66affSColin Finck {
1080c2c66affSColin Finck u = i >> 1;
1081c2c66affSColin Finck v = i & 1;
1082c2c66affSColin Finck
1083c2c66affSColin Finck if( verbose != 0 )
1084c2c66affSColin Finck mbedtls_printf( " CAMELLIA-CTR-128 (%s): ",
1085c2c66affSColin Finck ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
1086c2c66affSColin Finck
1087c2c66affSColin Finck memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 );
1088c2c66affSColin Finck memcpy( key, camellia_test_ctr_key[u], 16 );
1089c2c66affSColin Finck
1090c2c66affSColin Finck offset = 0;
1091c2c66affSColin Finck mbedtls_camellia_setkey_enc( &ctx, key, 128 );
1092c2c66affSColin Finck
1093c2c66affSColin Finck if( v == MBEDTLS_CAMELLIA_DECRYPT )
1094c2c66affSColin Finck {
1095c2c66affSColin Finck len = camellia_test_ctr_len[u];
1096c2c66affSColin Finck memcpy( buf, camellia_test_ctr_ct[u], len );
1097c2c66affSColin Finck
1098c2c66affSColin Finck mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
1099c2c66affSColin Finck buf, buf );
1100c2c66affSColin Finck
1101c2c66affSColin Finck if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 )
1102c2c66affSColin Finck {
1103c2c66affSColin Finck if( verbose != 0 )
1104c2c66affSColin Finck mbedtls_printf( "failed\n" );
1105*103a79ceSThomas Faber goto exit;
1106c2c66affSColin Finck }
1107c2c66affSColin Finck }
1108c2c66affSColin Finck else
1109c2c66affSColin Finck {
1110c2c66affSColin Finck len = camellia_test_ctr_len[u];
1111c2c66affSColin Finck memcpy( buf, camellia_test_ctr_pt[u], len );
1112c2c66affSColin Finck
1113c2c66affSColin Finck mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
1114c2c66affSColin Finck buf, buf );
1115c2c66affSColin Finck
1116c2c66affSColin Finck if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 )
1117c2c66affSColin Finck {
1118c2c66affSColin Finck if( verbose != 0 )
1119c2c66affSColin Finck mbedtls_printf( "failed\n" );
1120*103a79ceSThomas Faber goto exit;
1121c2c66affSColin Finck }
1122c2c66affSColin Finck }
1123c2c66affSColin Finck
1124c2c66affSColin Finck if( verbose != 0 )
1125c2c66affSColin Finck mbedtls_printf( "passed\n" );
1126c2c66affSColin Finck }
1127c2c66affSColin Finck
1128c2c66affSColin Finck if( verbose != 0 )
1129c2c66affSColin Finck mbedtls_printf( "\n" );
1130c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CTR */
1131c2c66affSColin Finck
1132*103a79ceSThomas Faber ret = 0;
1133*103a79ceSThomas Faber
1134*103a79ceSThomas Faber exit:
1135*103a79ceSThomas Faber mbedtls_camellia_free( &ctx );
1136*103a79ceSThomas Faber return( ret );
1137c2c66affSColin Finck }
1138c2c66affSColin Finck
1139c2c66affSColin Finck #endif /* MBEDTLS_SELF_TEST */
1140c2c66affSColin Finck
1141c2c66affSColin Finck #endif /* MBEDTLS_CAMELLIA_C */
1142