blob: b1c0a08ca23ab020e37e91c1c2f7cebf8dab0fda [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * Camellia implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander817466c2018-05-22 13:49:31 +02006 */
7/*
8 * The Camellia block cipher was designed by NTT and Mitsubishi Electric
9 * Corporation.
10 *
11 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
12 */
13
Jerome Forissier79013242021-07-28 10:24:04 +020014#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020015
16#if defined(MBEDTLS_CAMELLIA_C)
17
18#include "mbedtls/camellia.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010019#include "mbedtls/platform_util.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020020
21#include <string.h>
22
Jens Wiklander817466c2018-05-22 13:49:31 +020023#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020024
25#if !defined(MBEDTLS_CAMELLIA_ALT)
26
Jens Wiklander817466c2018-05-22 13:49:31 +020027static const unsigned char SIGMA_CHARS[6][8] =
28{
29 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
30 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
31 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
32 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
33 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
34 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
35};
36
37#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
38
39static const unsigned char FSb[256] =
40{
Jens Wiklander32b31802023-10-06 16:59:46 +020041 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
42 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
43 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
44 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
45 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
46 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
47 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
48 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
49 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
50 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
51 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
52 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
53 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
54 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
55 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
56 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Jens Wiklander817466c2018-05-22 13:49:31 +020057};
58
59#define SBOX1(n) FSb[(n)]
Jens Wiklander32b31802023-10-06 16:59:46 +020060#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
61#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Jens Wiklander817466c2018-05-22 13:49:31 +020062#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
63
64#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
65
66static const unsigned char FSb[256] =
67{
Jens Wiklander32b31802023-10-06 16:59:46 +020068 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
69 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
70 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
71 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
72 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
73 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
74 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
75 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
76 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
77 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
78 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
79 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
80 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
81 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
82 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
83 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Jens Wiklander817466c2018-05-22 13:49:31 +020084};
85
86static const unsigned char FSb2[256] =
87{
Jens Wiklander32b31802023-10-06 16:59:46 +020088 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
89 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
90 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
91 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
92 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
93 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
94 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
95 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
96 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
97 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
98 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
99 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
100 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
101 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
102 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
103 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Jens Wiklander817466c2018-05-22 13:49:31 +0200104};
105
106static const unsigned char FSb3[256] =
107{
Jens Wiklander32b31802023-10-06 16:59:46 +0200108 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
109 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
110 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
111 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
112 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
113 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
114 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
115 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
116 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
117 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
118 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
119 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
120 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
121 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
122 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
123 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Jens Wiklander817466c2018-05-22 13:49:31 +0200124};
125
126static const unsigned char FSb4[256] =
127{
Jens Wiklander32b31802023-10-06 16:59:46 +0200128 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
129 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
130 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
131 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
132 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
133 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
134 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
135 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
136 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
137 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
138 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
139 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
140 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
141 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
142 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
143 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Jens Wiklander817466c2018-05-22 13:49:31 +0200144};
145
146#define SBOX1(n) FSb[(n)]
147#define SBOX2(n) FSb2[(n)]
148#define SBOX3(n) FSb3[(n)]
149#define SBOX4(n) FSb4[(n)]
150
151#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
152
153static const unsigned char shifts[2][4][4] =
154{
155 {
156 { 1, 1, 1, 1 }, /* KL */
157 { 0, 0, 0, 0 }, /* KR */
158 { 1, 1, 1, 1 }, /* KA */
159 { 0, 0, 0, 0 } /* KB */
160 },
161 {
162 { 1, 0, 1, 1 }, /* KL */
163 { 1, 1, 0, 1 }, /* KR */
164 { 1, 1, 1, 0 }, /* KA */
165 { 1, 1, 0, 1 } /* KB */
166 }
167};
168
169static const signed char indexes[2][4][20] =
170{
171 {
172 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
Jens Wiklander32b31802023-10-06 16:59:46 +0200173 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
Jens Wiklander817466c2018-05-22 13:49:31 +0200174 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
175 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
176 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
Jens Wiklander32b31802023-10-06 16:59:46 +0200177 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
Jens Wiklander817466c2018-05-22 13:49:31 +0200178 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
179 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
180 },
181 {
182 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
Jens Wiklander32b31802023-10-06 16:59:46 +0200183 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
Jens Wiklander817466c2018-05-22 13:49:31 +0200184 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
185 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
186 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
187 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
188 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
Jens Wiklander32b31802023-10-06 16:59:46 +0200189 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
Jens Wiklander817466c2018-05-22 13:49:31 +0200190 }
191};
192
193static const signed char transposes[2][20] =
194{
195 {
196 21, 22, 23, 20,
197 -1, -1, -1, -1,
198 18, 19, 16, 17,
199 11, 8, 9, 10,
200 15, 12, 13, 14
201 },
202 {
203 25, 26, 27, 24,
204 29, 30, 31, 28,
205 18, 19, 16, 17,
206 -1, -1, -1, -1,
207 -1, -1, -1, -1
208 }
209};
210
211/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
212#define ROTL(DEST, SRC, SHIFT) \
Jens Wiklander32b31802023-10-06 16:59:46 +0200213 { \
214 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
215 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
216 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
217 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
218 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200219
220#define FL(XL, XR, KL, KR) \
Jens Wiklander32b31802023-10-06 16:59:46 +0200221 { \
222 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
223 (XL) = ((XR) | (KR)) ^ (XL); \
224 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200225
226#define FLInv(YL, YR, KL, KR) \
Jens Wiklander32b31802023-10-06 16:59:46 +0200227 { \
228 (YL) = ((YR) | (KR)) ^ (YL); \
229 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
230 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200231
232#define SHIFT_AND_PLACE(INDEX, OFFSET) \
Jens Wiklander32b31802023-10-06 16:59:46 +0200233 { \
234 TK[0] = KC[(OFFSET) * 4 + 0]; \
235 TK[1] = KC[(OFFSET) * 4 + 1]; \
236 TK[2] = KC[(OFFSET) * 4 + 2]; \
237 TK[3] = KC[(OFFSET) * 4 + 3]; \
Jens Wiklander817466c2018-05-22 13:49:31 +0200238 \
Jens Wiklander32b31802023-10-06 16:59:46 +0200239 for (i = 1; i <= 4; i++) \
240 if (shifts[(INDEX)][(OFFSET)][i -1]) \
241 ROTL(TK + i * 4, TK, (15 * i) % 32); \
Jens Wiklander817466c2018-05-22 13:49:31 +0200242 \
Jens Wiklander32b31802023-10-06 16:59:46 +0200243 for (i = 0; i < 20; i++) \
244 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
245 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
Jens Wiklander817466c2018-05-22 13:49:31 +0200246 } \
Jens Wiklander32b31802023-10-06 16:59:46 +0200247 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200248
Jens Wiklander32b31802023-10-06 16:59:46 +0200249static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
250 uint32_t z[2])
Jens Wiklander817466c2018-05-22 13:49:31 +0200251{
252 uint32_t I0, I1;
253 I0 = x[0] ^ k[0];
254 I1 = x[1] ^ k[1];
255
Jens Wiklander32b31802023-10-06 16:59:46 +0200256 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
257 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
258 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
259 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
260 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
261 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
262 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
263 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
Jens Wiklander817466c2018-05-22 13:49:31 +0200264
265 I0 ^= (I1 << 8) | (I1 >> 24);
266 I1 ^= (I0 << 16) | (I0 >> 16);
267 I0 ^= (I1 >> 8) | (I1 << 24);
268 I1 ^= (I0 >> 8) | (I0 << 24);
269
270 z[0] ^= I1;
271 z[1] ^= I0;
272}
273
Jens Wiklander32b31802023-10-06 16:59:46 +0200274void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200275{
Jens Wiklander32b31802023-10-06 16:59:46 +0200276 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200277}
278
Jens Wiklander32b31802023-10-06 16:59:46 +0200279void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200280{
Jens Wiklander32b31802023-10-06 16:59:46 +0200281 if (ctx == NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200282 return;
Jens Wiklander32b31802023-10-06 16:59:46 +0200283 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200284
Jens Wiklander32b31802023-10-06 16:59:46 +0200285 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
Jens Wiklander817466c2018-05-22 13:49:31 +0200286}
287
288/*
289 * Camellia key schedule (encryption)
290 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200291int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
292 const unsigned char *key,
293 unsigned int keybits)
Jens Wiklander817466c2018-05-22 13:49:31 +0200294{
295 int idx;
296 size_t i;
297 uint32_t *RK;
298 unsigned char t[64];
299 uint32_t SIGMA[6][2];
300 uint32_t KC[16];
301 uint32_t TK[20];
302
303 RK = ctx->rk;
304
Jens Wiklander32b31802023-10-06 16:59:46 +0200305 memset(t, 0, 64);
306 memset(RK, 0, sizeof(ctx->rk));
Jens Wiklander817466c2018-05-22 13:49:31 +0200307
Jens Wiklander32b31802023-10-06 16:59:46 +0200308 switch (keybits) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200309 case 128: ctx->nr = 3; idx = 0; break;
310 case 192:
311 case 256: ctx->nr = 4; idx = 1; break;
Jens Wiklander32b31802023-10-06 16:59:46 +0200312 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Jens Wiklander817466c2018-05-22 13:49:31 +0200313 }
314
Jens Wiklander32b31802023-10-06 16:59:46 +0200315 for (i = 0; i < keybits / 8; ++i) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200316 t[i] = key[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200317 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200318
Jens Wiklander32b31802023-10-06 16:59:46 +0200319 if (keybits == 192) {
320 for (i = 0; i < 8; i++) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200321 t[24 + i] = ~t[16 + i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200322 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200323 }
324
325 /*
326 * Prepare SIGMA values
327 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200328 for (i = 0; i < 6; i++) {
329 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
330 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
Jens Wiklander817466c2018-05-22 13:49:31 +0200331 }
332
333 /*
334 * Key storage in KC
335 * Order: KL, KR, KA, KB
336 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200337 memset(KC, 0, sizeof(KC));
Jens Wiklander817466c2018-05-22 13:49:31 +0200338
339 /* Store KL, KR */
Jens Wiklander32b31802023-10-06 16:59:46 +0200340 for (i = 0; i < 8; i++) {
341 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
342 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200343
344 /* Generate KA */
Jens Wiklander32b31802023-10-06 16:59:46 +0200345 for (i = 0; i < 4; ++i) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200346 KC[8 + i] = KC[i] ^ KC[4 + i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200347 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200348
Jens Wiklander32b31802023-10-06 16:59:46 +0200349 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
350 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
Jens Wiklander817466c2018-05-22 13:49:31 +0200351
Jens Wiklander32b31802023-10-06 16:59:46 +0200352 for (i = 0; i < 4; ++i) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200353 KC[8 + i] ^= KC[i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200354 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200355
Jens Wiklander32b31802023-10-06 16:59:46 +0200356 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
357 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
Jens Wiklander817466c2018-05-22 13:49:31 +0200358
Jens Wiklander32b31802023-10-06 16:59:46 +0200359 if (keybits > 128) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200360 /* Generate KB */
Jens Wiklander32b31802023-10-06 16:59:46 +0200361 for (i = 0; i < 4; ++i) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200362 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Jens Wiklander32b31802023-10-06 16:59:46 +0200363 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200364
Jens Wiklander32b31802023-10-06 16:59:46 +0200365 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
366 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Jens Wiklander817466c2018-05-22 13:49:31 +0200367 }
368
369 /*
370 * Generating subkeys
371 */
372
373 /* Manipulating KL */
Jens Wiklander32b31802023-10-06 16:59:46 +0200374 SHIFT_AND_PLACE(idx, 0);
Jens Wiklander817466c2018-05-22 13:49:31 +0200375
376 /* Manipulating KR */
Jens Wiklander32b31802023-10-06 16:59:46 +0200377 if (keybits > 128) {
378 SHIFT_AND_PLACE(idx, 1);
Jens Wiklander817466c2018-05-22 13:49:31 +0200379 }
380
381 /* Manipulating KA */
Jens Wiklander32b31802023-10-06 16:59:46 +0200382 SHIFT_AND_PLACE(idx, 2);
Jens Wiklander817466c2018-05-22 13:49:31 +0200383
384 /* Manipulating KB */
Jens Wiklander32b31802023-10-06 16:59:46 +0200385 if (keybits > 128) {
386 SHIFT_AND_PLACE(idx, 3);
Jens Wiklander817466c2018-05-22 13:49:31 +0200387 }
388
389 /* Do transpositions */
Jens Wiklander32b31802023-10-06 16:59:46 +0200390 for (i = 0; i < 20; i++) {
391 if (transposes[idx][i] != -1) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200392 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
393 }
394 }
395
Jens Wiklander32b31802023-10-06 16:59:46 +0200396 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200397}
398
399/*
400 * Camellia key schedule (decryption)
401 */
Tom Van Eyckc1633172024-04-09 18:44:13 +0200402#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200403int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
404 const unsigned char *key,
405 unsigned int keybits)
Jens Wiklander817466c2018-05-22 13:49:31 +0200406{
407 int idx, ret;
408 size_t i;
409 mbedtls_camellia_context cty;
410 uint32_t *RK;
411 uint32_t *SK;
412
Jens Wiklander32b31802023-10-06 16:59:46 +0200413 mbedtls_camellia_init(&cty);
Jens Wiklander817466c2018-05-22 13:49:31 +0200414
415 /* Also checks keybits */
Jens Wiklander32b31802023-10-06 16:59:46 +0200416 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200417 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +0200418 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200419
420 ctx->nr = cty.nr;
Jens Wiklander32b31802023-10-06 16:59:46 +0200421 idx = (ctx->nr == 4);
Jens Wiklander817466c2018-05-22 13:49:31 +0200422
423 RK = ctx->rk;
424 SK = cty.rk + 24 * 2 + 8 * idx * 2;
425
426 *RK++ = *SK++;
427 *RK++ = *SK++;
428 *RK++ = *SK++;
429 *RK++ = *SK++;
430
Jens Wiklander32b31802023-10-06 16:59:46 +0200431 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200432 *RK++ = *SK++;
433 *RK++ = *SK++;
434 }
435
436 SK -= 2;
437
438 *RK++ = *SK++;
439 *RK++ = *SK++;
440 *RK++ = *SK++;
441 *RK++ = *SK++;
442
443exit:
Jens Wiklander32b31802023-10-06 16:59:46 +0200444 mbedtls_camellia_free(&cty);
Jens Wiklander817466c2018-05-22 13:49:31 +0200445
Jens Wiklander32b31802023-10-06 16:59:46 +0200446 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200447}
Tom Van Eyckc1633172024-04-09 18:44:13 +0200448#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jens Wiklander817466c2018-05-22 13:49:31 +0200449
450/*
451 * Camellia-ECB block encryption/decryption
452 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200453int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
454 int mode,
455 const unsigned char input[16],
456 unsigned char output[16])
Jens Wiklander817466c2018-05-22 13:49:31 +0200457{
458 int NR;
459 uint32_t *RK, X[4];
Jens Wiklander32b31802023-10-06 16:59:46 +0200460 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
461 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
462 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200463
Jens Wiklander32b31802023-10-06 16:59:46 +0200464 ((void) mode);
Jens Wiklander817466c2018-05-22 13:49:31 +0200465
466 NR = ctx->nr;
467 RK = ctx->rk;
468
Jens Wiklander32b31802023-10-06 16:59:46 +0200469 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
470 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
471 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
472 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
Jens Wiklander817466c2018-05-22 13:49:31 +0200473
474 X[0] ^= *RK++;
475 X[1] ^= *RK++;
476 X[2] ^= *RK++;
477 X[3] ^= *RK++;
478
Jens Wiklander32b31802023-10-06 16:59:46 +0200479 while (NR) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200480 --NR;
Jens Wiklander32b31802023-10-06 16:59:46 +0200481 camellia_feistel(X, RK, X + 2);
Jens Wiklander817466c2018-05-22 13:49:31 +0200482 RK += 2;
Jens Wiklander32b31802023-10-06 16:59:46 +0200483 camellia_feistel(X + 2, RK, X);
Jens Wiklander817466c2018-05-22 13:49:31 +0200484 RK += 2;
Jens Wiklander32b31802023-10-06 16:59:46 +0200485 camellia_feistel(X, RK, X + 2);
Jens Wiklander817466c2018-05-22 13:49:31 +0200486 RK += 2;
Jens Wiklander32b31802023-10-06 16:59:46 +0200487 camellia_feistel(X + 2, RK, X);
Jens Wiklander817466c2018-05-22 13:49:31 +0200488 RK += 2;
Jens Wiklander32b31802023-10-06 16:59:46 +0200489 camellia_feistel(X, RK, X + 2);
Jens Wiklander817466c2018-05-22 13:49:31 +0200490 RK += 2;
Jens Wiklander32b31802023-10-06 16:59:46 +0200491 camellia_feistel(X + 2, RK, X);
Jens Wiklander817466c2018-05-22 13:49:31 +0200492 RK += 2;
493
Jens Wiklander32b31802023-10-06 16:59:46 +0200494 if (NR) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200495 FL(X[0], X[1], RK[0], RK[1]);
496 RK += 2;
497 FLInv(X[2], X[3], RK[0], RK[1]);
498 RK += 2;
499 }
500 }
501
502 X[2] ^= *RK++;
503 X[3] ^= *RK++;
504 X[0] ^= *RK++;
505 X[1] ^= *RK++;
506
Jens Wiklander32b31802023-10-06 16:59:46 +0200507 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
508 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
509 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
510 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
Jens Wiklander817466c2018-05-22 13:49:31 +0200511
Jens Wiklander32b31802023-10-06 16:59:46 +0200512 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200513}
514
515#if defined(MBEDTLS_CIPHER_MODE_CBC)
516/*
517 * Camellia-CBC buffer encryption/decryption
518 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200519int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
520 int mode,
521 size_t length,
522 unsigned char iv[16],
523 const unsigned char *input,
524 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200525{
Jens Wiklander817466c2018-05-22 13:49:31 +0200526 unsigned char temp[16];
Jens Wiklander32b31802023-10-06 16:59:46 +0200527 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
528 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
529 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200530
Jens Wiklander32b31802023-10-06 16:59:46 +0200531 if (length % 16) {
532 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
533 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200534
Jens Wiklander32b31802023-10-06 16:59:46 +0200535 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
536 while (length > 0) {
537 memcpy(temp, input, 16);
538 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
Jens Wiklander817466c2018-05-22 13:49:31 +0200539
Jens Wiklander32b31802023-10-06 16:59:46 +0200540 mbedtls_xor(output, output, iv, 16);
Jens Wiklander817466c2018-05-22 13:49:31 +0200541
Jens Wiklander32b31802023-10-06 16:59:46 +0200542 memcpy(iv, temp, 16);
Jens Wiklander817466c2018-05-22 13:49:31 +0200543
544 input += 16;
545 output += 16;
546 length -= 16;
547 }
Jens Wiklander32b31802023-10-06 16:59:46 +0200548 } else {
549 while (length > 0) {
550 mbedtls_xor(output, input, iv, 16);
Jens Wiklander817466c2018-05-22 13:49:31 +0200551
Jens Wiklander32b31802023-10-06 16:59:46 +0200552 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
553 memcpy(iv, output, 16);
Jens Wiklander817466c2018-05-22 13:49:31 +0200554
555 input += 16;
556 output += 16;
557 length -= 16;
558 }
559 }
560
Jens Wiklander32b31802023-10-06 16:59:46 +0200561 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200562}
563#endif /* MBEDTLS_CIPHER_MODE_CBC */
564
565#if defined(MBEDTLS_CIPHER_MODE_CFB)
566/*
567 * Camellia-CFB128 buffer encryption/decryption
568 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200569int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
570 int mode,
571 size_t length,
572 size_t *iv_off,
573 unsigned char iv[16],
574 const unsigned char *input,
575 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200576{
577 int c;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100578 size_t n;
Jens Wiklander32b31802023-10-06 16:59:46 +0200579 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
580 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
581 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100582
583 n = *iv_off;
Jens Wiklander32b31802023-10-06 16:59:46 +0200584 if (n >= 16) {
585 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
586 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200587
Jens Wiklander32b31802023-10-06 16:59:46 +0200588 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
589 while (length--) {
590 if (n == 0) {
591 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
592 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200593
594 c = *input++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200595 *output++ = (unsigned char) (c ^ iv[n]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200596 iv[n] = (unsigned char) c;
597
Jens Wiklander32b31802023-10-06 16:59:46 +0200598 n = (n + 1) & 0x0F;
Jens Wiklander817466c2018-05-22 13:49:31 +0200599 }
Jens Wiklander32b31802023-10-06 16:59:46 +0200600 } else {
601 while (length--) {
602 if (n == 0) {
603 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
604 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200605
Jens Wiklander32b31802023-10-06 16:59:46 +0200606 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Jens Wiklander817466c2018-05-22 13:49:31 +0200607
Jens Wiklander32b31802023-10-06 16:59:46 +0200608 n = (n + 1) & 0x0F;
Jens Wiklander817466c2018-05-22 13:49:31 +0200609 }
610 }
611
612 *iv_off = n;
613
Jens Wiklander32b31802023-10-06 16:59:46 +0200614 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200615}
616#endif /* MBEDTLS_CIPHER_MODE_CFB */
617
618#if defined(MBEDTLS_CIPHER_MODE_CTR)
619/*
620 * Camellia-CTR buffer encryption/decryption
621 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200622int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
623 size_t length,
624 size_t *nc_off,
625 unsigned char nonce_counter[16],
626 unsigned char stream_block[16],
627 const unsigned char *input,
628 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +0200629{
630 int c, i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100631 size_t n;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100632
633 n = *nc_off;
Jens Wiklander32b31802023-10-06 16:59:46 +0200634 if (n >= 16) {
635 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
636 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200637
Jens Wiklander32b31802023-10-06 16:59:46 +0200638 while (length--) {
639 if (n == 0) {
640 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
641 stream_block);
Jens Wiklander817466c2018-05-22 13:49:31 +0200642
Jens Wiklander32b31802023-10-06 16:59:46 +0200643 for (i = 16; i > 0; i--) {
644 if (++nonce_counter[i - 1] != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200645 break;
Jens Wiklander32b31802023-10-06 16:59:46 +0200646 }
647 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200648 }
649 c = *input++;
Jens Wiklander32b31802023-10-06 16:59:46 +0200650 *output++ = (unsigned char) (c ^ stream_block[n]);
Jens Wiklander817466c2018-05-22 13:49:31 +0200651
Jens Wiklander32b31802023-10-06 16:59:46 +0200652 n = (n + 1) & 0x0F;
Jens Wiklander817466c2018-05-22 13:49:31 +0200653 }
654
655 *nc_off = n;
656
Jens Wiklander32b31802023-10-06 16:59:46 +0200657 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200658}
659#endif /* MBEDTLS_CIPHER_MODE_CTR */
660#endif /* !MBEDTLS_CAMELLIA_ALT */
661
662#if defined(MBEDTLS_SELF_TEST)
663
664/*
665 * Camellia test vectors from:
666 *
667 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
668 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
669 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
670 * (For each bitlength: Key 0, Nr 39)
671 */
672#define CAMELLIA_TESTS_ECB 2
673
674static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
675{
676 {
677 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
678 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
679 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
681 },
682 {
683 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
684 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
685 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
686 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
689 },
690 {
691 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
692 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
693 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
694 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
695 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
699 },
700};
701
702static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
703{
704 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
705 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
706 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
708};
709
710static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
711{
712 {
713 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
714 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
715 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
716 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
717 },
718 {
719 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
720 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
721 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
722 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
723 },
724 {
725 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
726 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
727 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
728 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
729 }
730};
731
732#if defined(MBEDTLS_CIPHER_MODE_CBC)
733#define CAMELLIA_TESTS_CBC 3
734
735static const unsigned char camellia_test_cbc_key[3][32] =
736{
Jens Wiklander32b31802023-10-06 16:59:46 +0200737 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
738 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Jens Wiklander817466c2018-05-22 13:49:31 +0200739 ,
Jens Wiklander32b31802023-10-06 16:59:46 +0200740 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
741 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
742 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Jens Wiklander817466c2018-05-22 13:49:31 +0200743 ,
Jens Wiklander32b31802023-10-06 16:59:46 +0200744 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
745 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
746 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
747 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200748};
749
750static const unsigned char camellia_test_cbc_iv[16] =
751
Jens Wiklander32b31802023-10-06 16:59:46 +0200752{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
753 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Jens Wiklander817466c2018-05-22 13:49:31 +0200754;
755
756static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
757{
758 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
759 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
760 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
761 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
762 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
763 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
764
765};
766
767static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
768{
769 {
770 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
771 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
772 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
773 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
774 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
775 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
776 },
777 {
778 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
779 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
780 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
781 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
782 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
783 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
784 },
785 {
786 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
787 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
788 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
789 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
790 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
791 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
792 }
793};
794#endif /* MBEDTLS_CIPHER_MODE_CBC */
795
796#if defined(MBEDTLS_CIPHER_MODE_CTR)
797/*
798 * Camellia-CTR test vectors from:
799 *
800 * http://www.faqs.org/rfcs/rfc5528.html
801 */
802
803static const unsigned char camellia_test_ctr_key[3][16] =
804{
805 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
806 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
807 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
808 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
809 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
810 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
811};
812
813static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
814{
815 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
817 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
818 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
819 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
820 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
821};
822
823static const unsigned char camellia_test_ctr_pt[3][48] =
824{
825 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
826 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
827
828 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
829 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
830 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
831 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
832
833 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
834 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
835 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
836 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
837 0x20, 0x21, 0x22, 0x23 }
838};
839
840static const unsigned char camellia_test_ctr_ct[3][48] =
841{
842 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
843 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
844 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
845 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
846 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
847 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
848 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
849 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
850 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
851 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
852 0xDF, 0x50, 0x86, 0x96 }
853};
854
855static const int camellia_test_ctr_len[3] =
Jens Wiklander32b31802023-10-06 16:59:46 +0200856{ 16, 32, 36 };
Jens Wiklander817466c2018-05-22 13:49:31 +0200857#endif /* MBEDTLS_CIPHER_MODE_CTR */
858
859/*
860 * Checkup routine
861 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200862int mbedtls_camellia_self_test(int verbose)
Jens Wiklander817466c2018-05-22 13:49:31 +0200863{
864 int i, j, u, v;
865 unsigned char key[32];
866 unsigned char buf[64];
867 unsigned char src[16];
868 unsigned char dst[16];
869#if defined(MBEDTLS_CIPHER_MODE_CBC)
870 unsigned char iv[16];
871#endif
872#if defined(MBEDTLS_CIPHER_MODE_CTR)
873 size_t offset, len;
874 unsigned char nonce_counter[16];
875 unsigned char stream_block[16];
876#endif
Jerome Forissier79013242021-07-28 10:24:04 +0200877 int ret = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200878
879 mbedtls_camellia_context ctx;
880
Jens Wiklander32b31802023-10-06 16:59:46 +0200881 mbedtls_camellia_init(&ctx);
882 memset(key, 0, 32);
Jens Wiklander817466c2018-05-22 13:49:31 +0200883
Jens Wiklander32b31802023-10-06 16:59:46 +0200884 for (j = 0; j < 6; j++) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200885 u = j >> 1;
Jens Wiklander32b31802023-10-06 16:59:46 +0200886 v = j & 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200887
Jens Wiklander32b31802023-10-06 16:59:46 +0200888 if (verbose != 0) {
889 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
890 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Jens Wiklander817466c2018-05-22 13:49:31 +0200891 }
892
Tom Van Eyckc1633172024-04-09 18:44:13 +0200893#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
894 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
895 if (verbose != 0) {
896 mbedtls_printf("skipped\n");
897 }
898 continue;
899 }
900#endif
901
Jens Wiklander32b31802023-10-06 16:59:46 +0200902 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
903 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Jens Wiklander817466c2018-05-22 13:49:31 +0200904
Tom Van Eyckc1633172024-04-09 18:44:13 +0200905#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200906 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
907 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
908 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
909 memcpy(dst, camellia_test_ecb_plain[i], 16);
Tom Van Eyckc1633172024-04-09 18:44:13 +0200910 } else
911#endif
912 { /* MBEDTLS_CAMELLIA_ENCRYPT */
Jens Wiklander32b31802023-10-06 16:59:46 +0200913 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
914 memcpy(src, camellia_test_ecb_plain[i], 16);
915 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
916 }
917
918 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
919
920 if (memcmp(buf, dst, 16) != 0) {
921 if (verbose != 0) {
922 mbedtls_printf("failed\n");
923 }
924 goto exit;
925 }
926 }
927
928 if (verbose != 0) {
929 mbedtls_printf("passed\n");
Jens Wiklander817466c2018-05-22 13:49:31 +0200930 }
931 }
932
Jens Wiklander32b31802023-10-06 16:59:46 +0200933 if (verbose != 0) {
934 mbedtls_printf("\n");
Jens Wiklander817466c2018-05-22 13:49:31 +0200935 }
936
Jens Wiklander817466c2018-05-22 13:49:31 +0200937#if defined(MBEDTLS_CIPHER_MODE_CBC)
938 /*
939 * CBC mode
940 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200941 for (j = 0; j < 6; j++) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200942 u = j >> 1;
943 v = j & 1;
944
Jens Wiklander32b31802023-10-06 16:59:46 +0200945 if (verbose != 0) {
946 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
947 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Jens Wiklander817466c2018-05-22 13:49:31 +0200948 }
949
Jens Wiklander32b31802023-10-06 16:59:46 +0200950 memcpy(src, camellia_test_cbc_iv, 16);
951 memcpy(dst, camellia_test_cbc_iv, 16);
952 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Jens Wiklander817466c2018-05-22 13:49:31 +0200953
Jens Wiklander32b31802023-10-06 16:59:46 +0200954 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
955 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
956 } else {
957 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
958 }
959
960 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
961
962 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
963 memcpy(iv, src, 16);
964 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
965 memcpy(dst, camellia_test_cbc_plain[i], 16);
Jens Wiklander817466c2018-05-22 13:49:31 +0200966 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
Jens Wiklander32b31802023-10-06 16:59:46 +0200967 memcpy(iv, dst, 16);
968 memcpy(src, camellia_test_cbc_plain[i], 16);
969 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Jens Wiklander817466c2018-05-22 13:49:31 +0200970 }
971
Jens Wiklander32b31802023-10-06 16:59:46 +0200972 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Jens Wiklander817466c2018-05-22 13:49:31 +0200973
Jens Wiklander32b31802023-10-06 16:59:46 +0200974 if (memcmp(buf, dst, 16) != 0) {
975 if (verbose != 0) {
976 mbedtls_printf("failed\n");
977 }
Jerome Forissier79013242021-07-28 10:24:04 +0200978 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +0200979 }
980 }
981
Jens Wiklander32b31802023-10-06 16:59:46 +0200982 if (verbose != 0) {
983 mbedtls_printf("passed\n");
984 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200985 }
986#endif /* MBEDTLS_CIPHER_MODE_CBC */
987
Jens Wiklander32b31802023-10-06 16:59:46 +0200988 if (verbose != 0) {
989 mbedtls_printf("\n");
990 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200991
992#if defined(MBEDTLS_CIPHER_MODE_CTR)
993 /*
994 * CTR mode
995 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200996 for (i = 0; i < 6; i++) {
Jens Wiklander817466c2018-05-22 13:49:31 +0200997 u = i >> 1;
998 v = i & 1;
999
Jens Wiklander32b31802023-10-06 16:59:46 +02001000 if (verbose != 0) {
1001 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
1002 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1003 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001004
Jens Wiklander32b31802023-10-06 16:59:46 +02001005 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1006 memcpy(key, camellia_test_ctr_key[u], 16);
Jens Wiklander817466c2018-05-22 13:49:31 +02001007
1008 offset = 0;
Jens Wiklander32b31802023-10-06 16:59:46 +02001009 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Jens Wiklander817466c2018-05-22 13:49:31 +02001010
Jens Wiklander32b31802023-10-06 16:59:46 +02001011 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001012 len = camellia_test_ctr_len[u];
Jens Wiklander32b31802023-10-06 16:59:46 +02001013 memcpy(buf, camellia_test_ctr_ct[u], len);
Jens Wiklander817466c2018-05-22 13:49:31 +02001014
Jens Wiklander32b31802023-10-06 16:59:46 +02001015 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1016 buf, buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02001017
Jens Wiklander32b31802023-10-06 16:59:46 +02001018 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1019 if (verbose != 0) {
1020 mbedtls_printf("failed\n");
1021 }
Jerome Forissier79013242021-07-28 10:24:04 +02001022 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +02001023 }
Jens Wiklander32b31802023-10-06 16:59:46 +02001024 } else {
Jens Wiklander817466c2018-05-22 13:49:31 +02001025 len = camellia_test_ctr_len[u];
Jens Wiklander32b31802023-10-06 16:59:46 +02001026 memcpy(buf, camellia_test_ctr_pt[u], len);
Jens Wiklander817466c2018-05-22 13:49:31 +02001027
Jens Wiklander32b31802023-10-06 16:59:46 +02001028 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1029 buf, buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02001030
Jens Wiklander32b31802023-10-06 16:59:46 +02001031 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1032 if (verbose != 0) {
1033 mbedtls_printf("failed\n");
1034 }
Jerome Forissier79013242021-07-28 10:24:04 +02001035 goto exit;
Jens Wiklander817466c2018-05-22 13:49:31 +02001036 }
1037 }
1038
Jens Wiklander32b31802023-10-06 16:59:46 +02001039 if (verbose != 0) {
1040 mbedtls_printf("passed\n");
1041 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001042 }
1043
Jens Wiklander32b31802023-10-06 16:59:46 +02001044 if (verbose != 0) {
1045 mbedtls_printf("\n");
1046 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001047#endif /* MBEDTLS_CIPHER_MODE_CTR */
1048
Jerome Forissier79013242021-07-28 10:24:04 +02001049 ret = 0;
1050
1051exit:
Jens Wiklander32b31802023-10-06 16:59:46 +02001052 mbedtls_camellia_free(&ctx);
1053 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02001054}
1055
1056#endif /* MBEDTLS_SELF_TEST */
1057
1058#endif /* MBEDTLS_CAMELLIA_C */