xref: /reactos/dll/3rdparty/mbedtls/camellia.c (revision 103a79ce)
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