blob: 122700be776799ae4b63e40d2714e9a5977877c0 [file] [log] [blame]
Paul Bakker38119b12009-01-10 23:31:23 +00001/*
2 * Camellia implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker38119b12009-01-10 23:31:23 +000018 */
19/*
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000020 * The Camellia block cipher was designed by NTT and Mitsubishi Electric
21 * Corporation.
Paul Bakker38119b12009-01-10 23:31:23 +000022 *
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000023 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
Paul Bakker38119b12009-01-10 23:31:23 +000024 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker38119b12009-01-10 23:31:23 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_CAMELLIA_C)
Paul Bakker38119b12009-01-10 23:31:23 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/camellia.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Paul Bakker38119b12009-01-10 23:31:23 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
Manuel Pégourié-Gonnard394608e2015-02-17 16:01:07 +010034
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#if !defined(MBEDTLS_CAMELLIA_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020038
Paul Bakker38119b12009-01-10 23:31:23 +000039static const unsigned char SIGMA_CHARS[6][8] =
40{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000041 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
42 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
43 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
44 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
45 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
46 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +000047};
48
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
Paul Bakkerfa049db2009-01-12 22:12:03 +000050
51static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +000052{
Gilles Peskine449bd832023-01-11 14:50:10 +010053 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
54 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
55 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
56 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
57 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
58 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
59 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
60 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
61 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
62 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
63 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
64 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
65 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
66 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
67 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
68 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakker38119b12009-01-10 23:31:23 +000069};
70
71#define SBOX1(n) FSb[(n)]
Gilles Peskine449bd832023-01-11 14:50:10 +010072#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
73#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +000074#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +000077
Paul Bakkerc32c6b52009-01-11 21:36:43 +000078static const unsigned char FSb[256] =
79{
Gilles Peskine449bd832023-01-11 14:50:10 +010080 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
81 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
82 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
83 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
84 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
85 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
86 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
87 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
88 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
89 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
90 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
91 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
92 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
93 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
94 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
95 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +000096};
97
98static const unsigned char FSb2[256] =
99{
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
101 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
102 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
103 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
104 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
105 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
106 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
107 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
108 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
109 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
110 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
111 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
112 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
113 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
114 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
115 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000116};
117
118static const unsigned char FSb3[256] =
119{
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
121 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
122 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
123 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
124 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
125 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
126 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
127 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
128 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
129 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
130 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
131 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
132 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
133 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
134 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
135 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000136};
137
138static const unsigned char FSb4[256] =
139{
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
141 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
142 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
143 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
144 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
145 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
146 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
147 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
148 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
149 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
150 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
151 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
152 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
153 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
154 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
155 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000156};
157
158#define SBOX1(n) FSb[(n)]
159#define SBOX2(n) FSb2[(n)]
160#define SBOX3(n) FSb3[(n)]
161#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000164
Paul Bakker38119b12009-01-10 23:31:23 +0000165static const unsigned char shifts[2][4][4] =
166{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000167 {
168 { 1, 1, 1, 1 }, /* KL */
169 { 0, 0, 0, 0 }, /* KR */
170 { 1, 1, 1, 1 }, /* KA */
171 { 0, 0, 0, 0 } /* KB */
172 },
173 {
174 { 1, 0, 1, 1 }, /* KL */
175 { 1, 1, 0, 1 }, /* KR */
176 { 1, 1, 1, 0 }, /* KA */
177 { 1, 1, 0, 1 } /* KB */
178 }
Paul Bakker38119b12009-01-10 23:31:23 +0000179};
180
Paul Bakker026c03b2009-03-28 17:53:03 +0000181static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000182{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000183 {
184 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000186 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
187 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
188 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000190 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
191 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
192 },
193 {
194 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000196 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
197 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
198 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
199 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
200 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000202 }
Paul Bakker38119b12009-01-10 23:31:23 +0000203};
204
Paul Bakker026c03b2009-03-28 17:53:03 +0000205static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000206{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000207 {
208 21, 22, 23, 20,
209 -1, -1, -1, -1,
210 18, 19, 16, 17,
211 11, 8, 9, 10,
212 15, 12, 13, 14
213 },
214 {
215 25, 26, 27, 24,
216 29, 30, 31, 28,
217 18, 19, 16, 17,
218 -1, -1, -1, -1,
219 -1, -1, -1, -1
220 }
Paul Bakker38119b12009-01-10 23:31:23 +0000221};
222
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000223/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000224#define ROTL(DEST, SRC, SHIFT) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 { \
226 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
227 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
228 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
229 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
230 }
Paul Bakker38119b12009-01-10 23:31:23 +0000231
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000232#define FL(XL, XR, KL, KR) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 { \
234 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
235 (XL) = ((XR) | (KR)) ^ (XL); \
236 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200237
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000238#define FLInv(YL, YR, KL, KR) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 { \
240 (YL) = ((YR) | (KR)) ^ (YL); \
241 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
242 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200243
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000244#define SHIFT_AND_PLACE(INDEX, OFFSET) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 { \
246 TK[0] = KC[(OFFSET) * 4 + 0]; \
247 TK[1] = KC[(OFFSET) * 4 + 1]; \
248 TK[2] = KC[(OFFSET) * 4 + 2]; \
249 TK[3] = KC[(OFFSET) * 4 + 3]; \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000250 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 for (i = 1; i <= 4; i++) \
252 if (shifts[(INDEX)][(OFFSET)][i -1]) \
253 ROTL(TK + i * 4, TK, (15 * i) % 32); \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000254 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 for (i = 0; i < 20; i++) \
256 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
257 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
Paul Bakker66d5d072014-06-17 16:39:18 +0200258 } \
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 }
Paul Bakker38119b12009-01-10 23:31:23 +0000260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
262 uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000263{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000264 uint32_t I0, I1;
265 I0 = x[0] ^ k[0];
266 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
269 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
270 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
271 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
272 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
273 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
274 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
275 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
Paul Bakker38119b12009-01-10 23:31:23 +0000276
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000277 I0 ^= (I1 << 8) | (I1 >> 24);
278 I1 ^= (I0 << 16) | (I0 >> 16);
279 I0 ^= (I1 >> 8) | (I1 << 24);
280 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000281
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000282 z[0] ^= I1;
283 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000284}
285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287{
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289}
290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200292{
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200294 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200298}
299
Paul Bakker38119b12009-01-10 23:31:23 +0000300/*
301 * Camellia key schedule (encryption)
302 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100303int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
304 const unsigned char *key,
305 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000306{
Paul Bakker23986e52011-04-24 08:57:21 +0000307 int idx;
308 size_t i;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000309 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000310 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000311 uint32_t SIGMA[6][2];
312 uint32_t KC[16];
313 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000314
315 RK = ctx->rk;
316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 memset(t, 0, 64);
318 memset(RK, 0, sizeof(ctx->rk));
Paul Bakker38119b12009-01-10 23:31:23 +0000319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 switch (keybits) {
Paul Bakker38119b12009-01-10 23:31:23 +0000321 case 128: ctx->nr = 3; idx = 0; break;
322 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000323 case 256: ctx->nr = 4; idx = 1; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Paul Bakker38119b12009-01-10 23:31:23 +0000325 }
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 for (i = 0; i < keybits / 8; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000328 t[i] = key[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 }
Paul Bakker38119b12009-01-10 23:31:23 +0000330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if (keybits == 192) {
332 for (i = 0; i < 8; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000333 t[24 + i] = ~t[16 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 }
Paul Bakker38119b12009-01-10 23:31:23 +0000335 }
336
Paul Bakker38119b12009-01-10 23:31:23 +0000337 /*
338 * Prepare SIGMA values
339 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 for (i = 0; i < 6; i++) {
341 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
342 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000343 }
344
345 /*
346 * Key storage in KC
347 * Order: KL, KR, KA, KB
348 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 memset(KC, 0, sizeof(KC));
Paul Bakker38119b12009-01-10 23:31:23 +0000350
351 /* Store KL, KR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 for (i = 0; i < 8; i++) {
353 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
354 }
Paul Bakker38119b12009-01-10 23:31:23 +0000355
356 /* Generate KA */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000358 KC[8 + i] = KC[i] ^ KC[4 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 }
Paul Bakker38119b12009-01-10 23:31:23 +0000360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
362 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000365 KC[8 + i] ^= KC[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 }
Paul Bakker38119b12009-01-10 23:31:23 +0000367
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
369 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 if (keybits > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000372 /* Generate KB */
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000374 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 }
Paul Bakker38119b12009-01-10 23:31:23 +0000376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
378 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000379 }
380
381 /*
382 * Generating subkeys
Paul Bakker9af723c2014-05-01 13:03:14 +0200383 */
Paul Bakker38119b12009-01-10 23:31:23 +0000384
385 /* Manipulating KL */
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 SHIFT_AND_PLACE(idx, 0);
Paul Bakker38119b12009-01-10 23:31:23 +0000387
388 /* Manipulating KR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 if (keybits > 128) {
390 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000391 }
392
393 /* Manipulating KA */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 SHIFT_AND_PLACE(idx, 2);
Paul Bakker38119b12009-01-10 23:31:23 +0000395
396 /* Manipulating KB */
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 if (keybits > 128) {
398 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000399 }
400
401 /* Do transpositions */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 for (i = 0; i < 20; i++) {
403 if (transposes[idx][i] != -1) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000404 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
405 }
Paul Bakker38119b12009-01-10 23:31:23 +0000406 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000409}
410
411/*
412 * Camellia key schedule (decryption)
413 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800414#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100415int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
416 const unsigned char *key,
417 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000418{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200419 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000420 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000422 uint32_t *RK;
423 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 mbedtls_camellia_init(&cty);
Paul Bakker38119b12009-01-10 23:31:23 +0000426
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200427 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200429 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 }
Paul Bakker38119b12009-01-10 23:31:23 +0000431
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200432 ctx->nr = cty.nr;
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 idx = (ctx->nr == 4);
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200434
435 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000436 SK = cty.rk + 24 * 2 + 8 * idx * 2;
437
438 *RK++ = *SK++;
439 *RK++ = *SK++;
440 *RK++ = *SK++;
441 *RK++ = *SK++;
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000444 *RK++ = *SK++;
445 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000446 }
447
448 SK -= 2;
449
450 *RK++ = *SK++;
451 *RK++ = *SK++;
452 *RK++ = *SK++;
453 *RK++ = *SK++;
454
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200455exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000459}
Yanray Wangb67b4742023-10-31 17:10:32 +0800460#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Paul Bakker38119b12009-01-10 23:31:23 +0000461
462/*
463 * Camellia-ECB block encryption/decryption
464 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
466 int mode,
467 const unsigned char input[16],
468 unsigned char output[16])
Paul Bakker38119b12009-01-10 23:31:23 +0000469{
Paul Bakker026c03b2009-03-28 17:53:03 +0000470 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000471 uint32_t *RK, X[4];
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100473 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 }
Paul Bakker38119b12009-01-10 23:31:23 +0000475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 ((void) mode);
Paul Bakkerc2547b02009-07-20 20:40:52 +0000477
Paul Bakker38119b12009-01-10 23:31:23 +0000478 NR = ctx->nr;
479 RK = ctx->rk;
480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
482 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
483 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
484 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000485
486 X[0] ^= *RK++;
487 X[1] ^= *RK++;
488 X[2] ^= *RK++;
489 X[3] ^= *RK++;
490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000492 --NR;
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000494 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000496 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000498 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000500 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000502 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000504 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 if (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000507 FL(X[0], X[1], RK[0], RK[1]);
508 RK += 2;
509 FLInv(X[2], X[3], RK[0], RK[1]);
510 RK += 2;
511 }
Paul Bakker38119b12009-01-10 23:31:23 +0000512 }
513
514 X[2] ^= *RK++;
515 X[3] ^= *RK++;
516 X[0] ^= *RK++;
517 X[1] ^= *RK++;
518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
520 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
521 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
522 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000525}
526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000528/*
529 * Camellia-CBC buffer encryption/decryption
530 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100531int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
532 int mode,
533 size_t length,
534 unsigned char iv[16],
535 const unsigned char *input,
536 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000537{
Paul Bakker38119b12009-01-10 23:31:23 +0000538 unsigned char temp[16];
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100540 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 }
Paul Bakker38119b12009-01-10 23:31:23 +0000542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 if (length % 16) {
544 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
545 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
548 while (length > 0) {
549 memcpy(temp, input, 16);
550 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
Paul Bakker38119b12009-01-10 23:31:23 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 mbedtls_xor(output, output, iv, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 memcpy(iv, temp, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000555
556 input += 16;
557 output += 16;
558 length -= 16;
559 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 } else {
561 while (length > 0) {
562 mbedtls_xor(output, input, iv, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
565 memcpy(iv, output, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000566
567 input += 16;
568 output += 16;
569 length -= 16;
570 }
571 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000574}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker38119b12009-01-10 23:31:23 +0000578/*
579 * Camellia-CFB128 buffer encryption/decryption
580 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100581int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
582 int mode,
583 size_t length,
584 size_t *iv_off,
585 unsigned char iv[16],
586 const unsigned char *input,
587 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000588{
Paul Bakker1ef71df2011-06-09 14:14:58 +0000589 int c;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500590 size_t n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100592 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500594
595 n = *iv_off;
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 if (n >= 16) {
597 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
598 }
Paul Bakker38119b12009-01-10 23:31:23 +0000599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
601 while (length--) {
602 if (n == 0) {
603 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
604 }
Paul Bakker38119b12009-01-10 23:31:23 +0000605
606 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker38119b12009-01-10 23:31:23 +0000608 iv[n] = (unsigned char) c;
609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000611 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 } else {
613 while (length--) {
614 if (n == 0) {
615 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
616 }
Paul Bakker38119b12009-01-10 23:31:23 +0000617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker38119b12009-01-10 23:31:23 +0000619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000621 }
622 }
623
624 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000627}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000629
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000631/*
632 * Camellia-CTR buffer encryption/decryption
633 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100634int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
635 size_t length,
636 size_t *nc_off,
637 unsigned char nonce_counter[16],
638 unsigned char stream_block[16],
639 const unsigned char *input,
640 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000641{
Paul Bakker369e14b2012-04-18 14:16:09 +0000642 int c, i;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500643 size_t n;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500644
645 n = *nc_off;
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 if (n >= 16) {
647 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
648 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 while (length--) {
651 if (n == 0) {
652 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
653 stream_block);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 for (i = 16; i > 0; i--) {
656 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +0000657 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 }
659 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000660 }
661 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000665 }
666
667 *nc_off = n;
668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 return 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000670}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671#endif /* MBEDTLS_CIPHER_MODE_CTR */
672#endif /* !MBEDTLS_CAMELLIA_ALT */
Paul Bakker38119b12009-01-10 23:31:23 +0000673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000675
Paul Bakker38119b12009-01-10 23:31:23 +0000676/*
677 * Camellia test vectors from:
678 *
679 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
680 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
681 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000682 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000683 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000684#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000685
686static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
687{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000688 {
689 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
690 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200691 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
693 },
694 {
695 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
696 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
697 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200698 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
701 },
702 {
703 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
704 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
705 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
706 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200707 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
711 },
Paul Bakker38119b12009-01-10 23:31:23 +0000712};
713
714static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
715{
716 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
717 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200718 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
720};
721
722static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
723{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000724 {
725 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
726 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
727 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
728 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
729 },
730 {
731 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
732 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
733 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
734 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
735 },
736 {
737 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
738 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
739 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
740 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
741 }
Paul Bakker38119b12009-01-10 23:31:23 +0000742};
743
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000745#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000746
747static const unsigned char camellia_test_cbc_key[3][32] =
748{
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
750 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000751 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
753 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
754 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000755 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
757 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
758 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
759 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000760};
761
762static const unsigned char camellia_test_cbc_iv[16] =
763
Gilles Peskine449bd832023-01-11 14:50:10 +0100764{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
765 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Paul Bakker38119b12009-01-10 23:31:23 +0000766;
767
768static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
769{
770 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
771 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
772 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
773 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
774 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
775 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
776
777};
778
779static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
780{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000781 {
782 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
783 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
784 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
785 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
786 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
787 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
788 },
789 {
790 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
791 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
792 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
793 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
794 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
795 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
796 },
797 {
798 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
799 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
800 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
801 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
802 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
803 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
804 }
Paul Bakker38119b12009-01-10 23:31:23 +0000805};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000809/*
810 * Camellia-CTR test vectors from:
811 *
812 * http://www.faqs.org/rfcs/rfc5528.html
813 */
814
815static const unsigned char camellia_test_ctr_key[3][16] =
816{
817 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
818 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
819 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
820 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
821 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
822 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
823};
824
825static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
826{
827 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
829 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
830 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
831 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
832 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
833};
834
835static const unsigned char camellia_test_ctr_pt[3][48] =
836{
837 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
838 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
839
840 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
841 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
842 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
843 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
844
845 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
846 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
847 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
848 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
849 0x20, 0x21, 0x22, 0x23 }
850};
851
852static const unsigned char camellia_test_ctr_ct[3][48] =
853{
854 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
855 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
856 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
857 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
858 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
859 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
860 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
861 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
862 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
863 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
864 0xDF, 0x50, 0x86, 0x96 }
865};
866
867static const int camellia_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100868{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000870
871/*
872 * Checkup routine
873 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100874int mbedtls_camellia_self_test(int verbose)
Paul Bakker38119b12009-01-10 23:31:23 +0000875{
Paul Bakker026c03b2009-03-28 17:53:03 +0000876 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000877 unsigned char key[32];
878 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000879 unsigned char src[16];
880 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000882 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200883#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000885 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000886 unsigned char nonce_counter[16];
887 unsigned char stream_block[16];
888#endif
Gilles Peskinec537aa82021-05-25 09:17:46 +0200889 int ret = 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000892
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 mbedtls_camellia_init(&ctx);
894 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000897 u = j >> 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000899
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (verbose != 0) {
901 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
902 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000903 }
Paul Bakker38119b12009-01-10 23:31:23 +0000904
Yanray Wangb67b4742023-10-31 17:10:32 +0800905#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang9141ad12023-08-24 14:53:16 +0800906 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
907 if (verbose != 0) {
908 mbedtls_printf("skipped\n");
909 }
910 continue;
911 }
912#endif
913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
915 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000916
Yanray Wangb67b4742023-10-31 17:10:32 +0800917#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
919 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
920 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
921 memcpy(dst, camellia_test_ecb_plain[i], 16);
Yanray Wang9141ad12023-08-24 14:53:16 +0800922 } else
923#endif
924 { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
926 memcpy(src, camellia_test_ecb_plain[i], 16);
927 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
928 }
929
930 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
931
932 if (memcmp(buf, dst, 16) != 0) {
933 if (verbose != 0) {
934 mbedtls_printf("failed\n");
935 }
936 goto exit;
937 }
938 }
939
940 if (verbose != 0) {
941 mbedtls_printf("passed\n");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000942 }
943 }
Paul Bakker38119b12009-01-10 23:31:23 +0000944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 if (verbose != 0) {
946 mbedtls_printf("\n");
Paul Bakker38119b12009-01-10 23:31:23 +0000947 }
948
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000950 /*
951 * CBC mode
952 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000954 u = j >> 1;
955 v = j & 1;
956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 if (verbose != 0) {
958 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
959 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000960 }
Paul Bakker38119b12009-01-10 23:31:23 +0000961
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 memcpy(src, camellia_test_cbc_iv, 16);
963 memcpy(dst, camellia_test_cbc_iv, 16);
964 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
967 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
968 } else {
969 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
970 }
971
972 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
973
974 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
975 memcpy(iv, src, 16);
976 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
977 memcpy(dst, camellia_test_cbc_plain[i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100978 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 memcpy(iv, dst, 16);
980 memcpy(src, camellia_test_cbc_plain[i], 16);
981 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100982 }
Paul Bakker38119b12009-01-10 23:31:23 +0000983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +0100985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 if (memcmp(buf, dst, 16) != 0) {
987 if (verbose != 0) {
988 mbedtls_printf("failed\n");
989 }
Gilles Peskinec537aa82021-05-25 09:17:46 +0200990 goto exit;
Janos Follath98e28a72016-05-31 14:03:54 +0100991 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000992 }
Paul Bakker38119b12009-01-10 23:31:23 +0000993
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 if (verbose != 0) {
995 mbedtls_printf("passed\n");
996 }
Paul Bakker38119b12009-01-10 23:31:23 +0000997 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 if (verbose != 0) {
1001 mbedtls_printf("\n");
1002 }
Paul Bakker38119b12009-01-10 23:31:23 +00001003
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001005 /*
1006 * CTR mode
1007 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001009 u = i >> 1;
1010 v = i & 1;
1011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 if (verbose != 0) {
1013 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
1014 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1015 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1018 memcpy(key, camellia_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001019
1020 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001024 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1028 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1031 if (verbose != 0) {
1032 mbedtls_printf("failed\n");
1033 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001034 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001035 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001037 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1041 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1044 if (verbose != 0) {
1045 mbedtls_printf("failed\n");
1046 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001047 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001048 }
1049 }
1050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 if (verbose != 0) {
1052 mbedtls_printf("passed\n");
1053 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001054 }
1055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 if (verbose != 0) {
1057 mbedtls_printf("\n");
1058 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001060
Gilles Peskinec537aa82021-05-25 09:17:46 +02001061 ret = 0;
1062
1063exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 mbedtls_camellia_free(&ctx);
1065 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +00001066}
1067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001069
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070#endif /* MBEDTLS_CAMELLIA_C */