blob: ce034d74fb601da1346a34de81caaebfe5074227 [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
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050039/* Parameter validation macros */
David Horstmannceeaeb92023-01-05 15:44:23 +000040#define CAMELLIA_VALIDATE_RET(cond) \
41 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
42#define CAMELLIA_VALIDATE(cond) \
43 MBEDTLS_INTERNAL_VALIDATE(cond)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050044
Paul Bakker38119b12009-01-10 23:31:23 +000045static const unsigned char SIGMA_CHARS[6][8] =
46{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000047 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
48 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
49 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
50 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
51 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
52 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +000053};
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
Paul Bakkerfa049db2009-01-12 22:12:03 +000056
57static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +000058{
David Horstmannceeaeb92023-01-05 15:44:23 +000059 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
60 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
61 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
62 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
63 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
64 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
65 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
66 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
67 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
68 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
69 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
70 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
71 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
72 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
73 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
74 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakker38119b12009-01-10 23:31:23 +000075};
76
77#define SBOX1(n) FSb[(n)]
David Horstmannceeaeb92023-01-05 15:44:23 +000078#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
79#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +000080#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
81
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +000083
Paul Bakkerc32c6b52009-01-11 21:36:43 +000084static const unsigned char FSb[256] =
85{
David Horstmannceeaeb92023-01-05 15:44:23 +000086 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
87 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
88 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
89 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
90 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
91 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
92 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
93 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
94 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
95 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
96 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
97 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
98 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
99 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
100 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
101 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000102};
103
104static const unsigned char FSb2[256] =
105{
David Horstmannceeaeb92023-01-05 15:44:23 +0000106 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
107 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
108 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
109 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
110 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
111 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
112 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
113 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
114 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
115 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
116 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
117 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
118 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
119 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
120 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
121 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000122};
123
124static const unsigned char FSb3[256] =
125{
David Horstmannceeaeb92023-01-05 15:44:23 +0000126 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
127 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
128 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
129 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
130 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
131 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
132 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
133 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
134 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
135 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
136 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
137 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
138 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
139 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
140 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
141 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000142};
143
144static const unsigned char FSb4[256] =
145{
David Horstmannceeaeb92023-01-05 15:44:23 +0000146 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
147 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
148 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
149 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
150 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
151 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
152 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
153 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
154 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
155 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
156 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
157 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
158 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
159 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
160 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
161 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000162};
163
164#define SBOX1(n) FSb[(n)]
165#define SBOX2(n) FSb2[(n)]
166#define SBOX3(n) FSb3[(n)]
167#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000170
Paul Bakker38119b12009-01-10 23:31:23 +0000171static const unsigned char shifts[2][4][4] =
172{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000173 {
174 { 1, 1, 1, 1 }, /* KL */
175 { 0, 0, 0, 0 }, /* KR */
176 { 1, 1, 1, 1 }, /* KA */
177 { 0, 0, 0, 0 } /* KB */
178 },
179 {
180 { 1, 0, 1, 1 }, /* KL */
181 { 1, 1, 0, 1 }, /* KR */
182 { 1, 1, 1, 0 }, /* KA */
183 { 1, 1, 0, 1 } /* KB */
184 }
Paul Bakker38119b12009-01-10 23:31:23 +0000185};
186
Paul Bakker026c03b2009-03-28 17:53:03 +0000187static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000188{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000189 {
190 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
David Horstmannceeaeb92023-01-05 15:44:23 +0000191 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000192 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
194 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
David Horstmannceeaeb92023-01-05 15:44:23 +0000195 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000196 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
197 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
198 },
199 {
200 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
David Horstmannceeaeb92023-01-05 15:44:23 +0000201 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000202 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
203 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
204 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
205 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
206 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
David Horstmannceeaeb92023-01-05 15:44:23 +0000207 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000208 }
Paul Bakker38119b12009-01-10 23:31:23 +0000209};
210
Paul Bakker026c03b2009-03-28 17:53:03 +0000211static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000212{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000213 {
214 21, 22, 23, 20,
215 -1, -1, -1, -1,
216 18, 19, 16, 17,
217 11, 8, 9, 10,
218 15, 12, 13, 14
219 },
220 {
221 25, 26, 27, 24,
222 29, 30, 31, 28,
223 18, 19, 16, 17,
224 -1, -1, -1, -1,
225 -1, -1, -1, -1
226 }
Paul Bakker38119b12009-01-10 23:31:23 +0000227};
228
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000229/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000230#define ROTL(DEST, SRC, SHIFT) \
David Horstmannceeaeb92023-01-05 15:44:23 +0000231 { \
232 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
233 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
234 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
235 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
236 }
Paul Bakker38119b12009-01-10 23:31:23 +0000237
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000238#define FL(XL, XR, KL, KR) \
David Horstmannceeaeb92023-01-05 15:44:23 +0000239 { \
240 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
241 (XL) = ((XR) | (KR)) ^ (XL); \
242 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200243
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000244#define FLInv(YL, YR, KL, KR) \
David Horstmannceeaeb92023-01-05 15:44:23 +0000245 { \
246 (YL) = ((YR) | (KR)) ^ (YL); \
247 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
248 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200249
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000250#define SHIFT_AND_PLACE(INDEX, OFFSET) \
David Horstmannceeaeb92023-01-05 15:44:23 +0000251 { \
252 TK[0] = KC[(OFFSET) * 4 + 0]; \
253 TK[1] = KC[(OFFSET) * 4 + 1]; \
254 TK[2] = KC[(OFFSET) * 4 + 2]; \
255 TK[3] = KC[(OFFSET) * 4 + 3]; \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000256 \
David Horstmannceeaeb92023-01-05 15:44:23 +0000257 for (i = 1; i <= 4; i++) \
258 if (shifts[(INDEX)][(OFFSET)][i -1]) \
259 ROTL(TK + i * 4, TK, (15 * i) % 32); \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000260 \
David Horstmannceeaeb92023-01-05 15:44:23 +0000261 for (i = 0; i < 20; i++) \
262 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
263 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
Paul Bakker66d5d072014-06-17 16:39:18 +0200264 } \
David Horstmannceeaeb92023-01-05 15:44:23 +0000265 }
Paul Bakker38119b12009-01-10 23:31:23 +0000266
David Horstmannceeaeb92023-01-05 15:44:23 +0000267static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
268 uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000269{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000270 uint32_t I0, I1;
271 I0 = x[0] ^ k[0];
272 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000273
David Horstmannceeaeb92023-01-05 15:44:23 +0000274 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
275 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
276 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
277 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
278 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
279 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
280 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
281 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
Paul Bakker38119b12009-01-10 23:31:23 +0000282
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000283 I0 ^= (I1 << 8) | (I1 >> 24);
284 I1 ^= (I0 << 16) | (I0 >> 16);
285 I0 ^= (I1 >> 8) | (I1 << 24);
286 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000287
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000288 z[0] ^= I1;
289 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000290}
291
David Horstmannceeaeb92023-01-05 15:44:23 +0000292void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200293{
David Horstmannceeaeb92023-01-05 15:44:23 +0000294 CAMELLIA_VALIDATE(ctx != NULL);
295 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200296}
297
David Horstmannceeaeb92023-01-05 15:44:23 +0000298void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200299{
David Horstmannceeaeb92023-01-05 15:44:23 +0000300 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200301 return;
David Horstmannceeaeb92023-01-05 15:44:23 +0000302 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200303
David Horstmannceeaeb92023-01-05 15:44:23 +0000304 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200305}
306
Paul Bakker38119b12009-01-10 23:31:23 +0000307/*
308 * Camellia key schedule (encryption)
309 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000310int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
311 const unsigned char *key,
312 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000313{
Paul Bakker23986e52011-04-24 08:57:21 +0000314 int idx;
315 size_t i;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000316 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000317 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000318 uint32_t SIGMA[6][2];
319 uint32_t KC[16];
320 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000321
David Horstmannceeaeb92023-01-05 15:44:23 +0000322 CAMELLIA_VALIDATE_RET(ctx != NULL);
323 CAMELLIA_VALIDATE_RET(key != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500324
Paul Bakker38119b12009-01-10 23:31:23 +0000325 RK = ctx->rk;
326
David Horstmannceeaeb92023-01-05 15:44:23 +0000327 memset(t, 0, 64);
328 memset(RK, 0, sizeof(ctx->rk));
Paul Bakker38119b12009-01-10 23:31:23 +0000329
David Horstmannceeaeb92023-01-05 15:44:23 +0000330 switch (keybits) {
Paul Bakker38119b12009-01-10 23:31:23 +0000331 case 128: ctx->nr = 3; idx = 0; break;
332 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000333 case 256: ctx->nr = 4; idx = 1; break;
David Horstmannceeaeb92023-01-05 15:44:23 +0000334 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Paul Bakker38119b12009-01-10 23:31:23 +0000335 }
336
David Horstmannceeaeb92023-01-05 15:44:23 +0000337 for (i = 0; i < keybits / 8; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000338 t[i] = key[i];
David Horstmannceeaeb92023-01-05 15:44:23 +0000339 }
Paul Bakker38119b12009-01-10 23:31:23 +0000340
David Horstmannceeaeb92023-01-05 15:44:23 +0000341 if (keybits == 192) {
342 for (i = 0; i < 8; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000343 t[24 + i] = ~t[16 + i];
David Horstmannceeaeb92023-01-05 15:44:23 +0000344 }
Paul Bakker38119b12009-01-10 23:31:23 +0000345 }
346
Paul Bakker38119b12009-01-10 23:31:23 +0000347 /*
348 * Prepare SIGMA values
349 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000350 for (i = 0; i < 6; i++) {
351 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
352 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000353 }
354
355 /*
356 * Key storage in KC
357 * Order: KL, KR, KA, KB
358 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000359 memset(KC, 0, sizeof(KC));
Paul Bakker38119b12009-01-10 23:31:23 +0000360
361 /* Store KL, KR */
David Horstmannceeaeb92023-01-05 15:44:23 +0000362 for (i = 0; i < 8; i++) {
363 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
364 }
Paul Bakker38119b12009-01-10 23:31:23 +0000365
366 /* Generate KA */
David Horstmannceeaeb92023-01-05 15:44:23 +0000367 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000368 KC[8 + i] = KC[i] ^ KC[4 + i];
David Horstmannceeaeb92023-01-05 15:44:23 +0000369 }
Paul Bakker38119b12009-01-10 23:31:23 +0000370
David Horstmannceeaeb92023-01-05 15:44:23 +0000371 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
372 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000373
David Horstmannceeaeb92023-01-05 15:44:23 +0000374 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000375 KC[8 + i] ^= KC[i];
David Horstmannceeaeb92023-01-05 15:44:23 +0000376 }
Paul Bakker38119b12009-01-10 23:31:23 +0000377
David Horstmannceeaeb92023-01-05 15:44:23 +0000378 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
379 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000380
David Horstmannceeaeb92023-01-05 15:44:23 +0000381 if (keybits > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000382 /* Generate KB */
David Horstmannceeaeb92023-01-05 15:44:23 +0000383 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000384 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
David Horstmannceeaeb92023-01-05 15:44:23 +0000385 }
Paul Bakker38119b12009-01-10 23:31:23 +0000386
David Horstmannceeaeb92023-01-05 15:44:23 +0000387 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
388 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000389 }
390
391 /*
392 * Generating subkeys
Paul Bakker9af723c2014-05-01 13:03:14 +0200393 */
Paul Bakker38119b12009-01-10 23:31:23 +0000394
395 /* Manipulating KL */
David Horstmannceeaeb92023-01-05 15:44:23 +0000396 SHIFT_AND_PLACE(idx, 0);
Paul Bakker38119b12009-01-10 23:31:23 +0000397
398 /* Manipulating KR */
David Horstmannceeaeb92023-01-05 15:44:23 +0000399 if (keybits > 128) {
400 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000401 }
402
403 /* Manipulating KA */
David Horstmannceeaeb92023-01-05 15:44:23 +0000404 SHIFT_AND_PLACE(idx, 2);
Paul Bakker38119b12009-01-10 23:31:23 +0000405
406 /* Manipulating KB */
David Horstmannceeaeb92023-01-05 15:44:23 +0000407 if (keybits > 128) {
408 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000409 }
410
411 /* Do transpositions */
David Horstmannceeaeb92023-01-05 15:44:23 +0000412 for (i = 0; i < 20; i++) {
413 if (transposes[idx][i] != -1) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000414 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
415 }
Paul Bakker38119b12009-01-10 23:31:23 +0000416 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000417
David Horstmannceeaeb92023-01-05 15:44:23 +0000418 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000419}
420
421/*
422 * Camellia key schedule (decryption)
423 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000424int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
425 const unsigned char *key,
426 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000427{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200428 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000429 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000431 uint32_t *RK;
432 uint32_t *SK;
David Horstmannceeaeb92023-01-05 15:44:23 +0000433 CAMELLIA_VALIDATE_RET(ctx != NULL);
434 CAMELLIA_VALIDATE_RET(key != NULL);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200435
David Horstmannceeaeb92023-01-05 15:44:23 +0000436 mbedtls_camellia_init(&cty);
Paul Bakker38119b12009-01-10 23:31:23 +0000437
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200438 /* Also checks keybits */
David Horstmannceeaeb92023-01-05 15:44:23 +0000439 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200440 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000441 }
Paul Bakker38119b12009-01-10 23:31:23 +0000442
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200443 ctx->nr = cty.nr;
David Horstmannceeaeb92023-01-05 15:44:23 +0000444 idx = (ctx->nr == 4);
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200445
446 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000447 SK = cty.rk + 24 * 2 + 8 * idx * 2;
448
449 *RK++ = *SK++;
450 *RK++ = *SK++;
451 *RK++ = *SK++;
452 *RK++ = *SK++;
453
David Horstmannceeaeb92023-01-05 15:44:23 +0000454 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000455 *RK++ = *SK++;
456 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000457 }
458
459 SK -= 2;
460
461 *RK++ = *SK++;
462 *RK++ = *SK++;
463 *RK++ = *SK++;
464 *RK++ = *SK++;
465
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200466exit:
David Horstmannceeaeb92023-01-05 15:44:23 +0000467 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000468
David Horstmannceeaeb92023-01-05 15:44:23 +0000469 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000470}
471
472/*
473 * Camellia-ECB block encryption/decryption
474 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000475int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
476 int mode,
477 const unsigned char input[16],
478 unsigned char output[16])
Paul Bakker38119b12009-01-10 23:31:23 +0000479{
Paul Bakker026c03b2009-03-28 17:53:03 +0000480 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000481 uint32_t *RK, X[4];
David Horstmannceeaeb92023-01-05 15:44:23 +0000482 CAMELLIA_VALIDATE_RET(ctx != NULL);
483 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
484 mode == MBEDTLS_CAMELLIA_DECRYPT);
485 CAMELLIA_VALIDATE_RET(input != NULL);
486 CAMELLIA_VALIDATE_RET(output != NULL);
Paul Bakker38119b12009-01-10 23:31:23 +0000487
David Horstmannceeaeb92023-01-05 15:44:23 +0000488 ((void) mode);
Paul Bakkerc2547b02009-07-20 20:40:52 +0000489
Paul Bakker38119b12009-01-10 23:31:23 +0000490 NR = ctx->nr;
491 RK = ctx->rk;
492
David Horstmannceeaeb92023-01-05 15:44:23 +0000493 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
494 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
495 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
496 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000497
498 X[0] ^= *RK++;
499 X[1] ^= *RK++;
500 X[2] ^= *RK++;
501 X[3] ^= *RK++;
502
David Horstmannceeaeb92023-01-05 15:44:23 +0000503 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000504 --NR;
David Horstmannceeaeb92023-01-05 15:44:23 +0000505 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000506 RK += 2;
David Horstmannceeaeb92023-01-05 15:44:23 +0000507 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000508 RK += 2;
David Horstmannceeaeb92023-01-05 15:44:23 +0000509 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000510 RK += 2;
David Horstmannceeaeb92023-01-05 15:44:23 +0000511 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000512 RK += 2;
David Horstmannceeaeb92023-01-05 15:44:23 +0000513 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000514 RK += 2;
David Horstmannceeaeb92023-01-05 15:44:23 +0000515 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000516 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000517
David Horstmannceeaeb92023-01-05 15:44:23 +0000518 if (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000519 FL(X[0], X[1], RK[0], RK[1]);
520 RK += 2;
521 FLInv(X[2], X[3], RK[0], RK[1]);
522 RK += 2;
523 }
Paul Bakker38119b12009-01-10 23:31:23 +0000524 }
525
526 X[2] ^= *RK++;
527 X[3] ^= *RK++;
528 X[0] ^= *RK++;
529 X[1] ^= *RK++;
530
David Horstmannceeaeb92023-01-05 15:44:23 +0000531 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
532 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
533 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
534 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000535
David Horstmannceeaeb92023-01-05 15:44:23 +0000536 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000537}
538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000540/*
541 * Camellia-CBC buffer encryption/decryption
542 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000543int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
544 int mode,
545 size_t length,
546 unsigned char iv[16],
547 const unsigned char *input,
548 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000549{
550 int i;
551 unsigned char temp[16];
David Horstmannceeaeb92023-01-05 15:44:23 +0000552 CAMELLIA_VALIDATE_RET(ctx != NULL);
553 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
554 mode == MBEDTLS_CAMELLIA_DECRYPT);
555 CAMELLIA_VALIDATE_RET(iv != NULL);
556 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
557 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
Paul Bakker38119b12009-01-10 23:31:23 +0000558
David Horstmannceeaeb92023-01-05 15:44:23 +0000559 if (length % 16) {
560 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
561 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000562
David Horstmannceeaeb92023-01-05 15:44:23 +0000563 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
564 while (length > 0) {
565 memcpy(temp, input, 16);
566 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
Paul Bakker38119b12009-01-10 23:31:23 +0000567
David Horstmannceeaeb92023-01-05 15:44:23 +0000568 for (i = 0; i < 16; i++) {
569 output[i] = (unsigned char) (output[i] ^ iv[i]);
570 }
Paul Bakker38119b12009-01-10 23:31:23 +0000571
David Horstmannceeaeb92023-01-05 15:44:23 +0000572 memcpy(iv, temp, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000573
574 input += 16;
575 output += 16;
576 length -= 16;
577 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000578 } else {
579 while (length > 0) {
580 for (i = 0; i < 16; i++) {
581 output[i] = (unsigned char) (input[i] ^ iv[i]);
582 }
Paul Bakker38119b12009-01-10 23:31:23 +0000583
David Horstmannceeaeb92023-01-05 15:44:23 +0000584 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
585 memcpy(iv, output, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000586
587 input += 16;
588 output += 16;
589 length -= 16;
590 }
591 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000592
David Horstmannceeaeb92023-01-05 15:44:23 +0000593 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000594}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker38119b12009-01-10 23:31:23 +0000598/*
599 * Camellia-CFB128 buffer encryption/decryption
600 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000601int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
602 int mode,
603 size_t length,
604 size_t *iv_off,
605 unsigned char iv[16],
606 const unsigned char *input,
607 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000608{
Paul Bakker1ef71df2011-06-09 14:14:58 +0000609 int c;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500610 size_t n;
David Horstmannceeaeb92023-01-05 15:44:23 +0000611 CAMELLIA_VALIDATE_RET(ctx != NULL);
612 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
613 mode == MBEDTLS_CAMELLIA_DECRYPT);
614 CAMELLIA_VALIDATE_RET(iv != NULL);
615 CAMELLIA_VALIDATE_RET(iv_off != NULL);
616 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
617 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500618
619 n = *iv_off;
David Horstmannceeaeb92023-01-05 15:44:23 +0000620 if (n >= 16) {
621 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
622 }
Paul Bakker38119b12009-01-10 23:31:23 +0000623
David Horstmannceeaeb92023-01-05 15:44:23 +0000624 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
625 while (length--) {
626 if (n == 0) {
627 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
628 }
Paul Bakker38119b12009-01-10 23:31:23 +0000629
630 c = *input++;
David Horstmannceeaeb92023-01-05 15:44:23 +0000631 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker38119b12009-01-10 23:31:23 +0000632 iv[n] = (unsigned char) c;
633
David Horstmannceeaeb92023-01-05 15:44:23 +0000634 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000635 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000636 } else {
637 while (length--) {
638 if (n == 0) {
639 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
640 }
Paul Bakker38119b12009-01-10 23:31:23 +0000641
David Horstmannceeaeb92023-01-05 15:44:23 +0000642 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker38119b12009-01-10 23:31:23 +0000643
David Horstmannceeaeb92023-01-05 15:44:23 +0000644 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000645 }
646 }
647
648 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000649
David Horstmannceeaeb92023-01-05 15:44:23 +0000650 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000651}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000653
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000655/*
656 * Camellia-CTR buffer encryption/decryption
657 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000658int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
659 size_t length,
660 size_t *nc_off,
661 unsigned char nonce_counter[16],
662 unsigned char stream_block[16],
663 const unsigned char *input,
664 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000665{
Paul Bakker369e14b2012-04-18 14:16:09 +0000666 int c, i;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500667 size_t n;
David Horstmannceeaeb92023-01-05 15:44:23 +0000668 CAMELLIA_VALIDATE_RET(ctx != NULL);
669 CAMELLIA_VALIDATE_RET(nonce_counter != NULL);
670 CAMELLIA_VALIDATE_RET(stream_block != NULL);
671 CAMELLIA_VALIDATE_RET(nc_off != NULL);
672 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
673 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500674
675 n = *nc_off;
David Horstmannceeaeb92023-01-05 15:44:23 +0000676 if (n >= 16) {
677 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
678 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000679
David Horstmannceeaeb92023-01-05 15:44:23 +0000680 while (length--) {
681 if (n == 0) {
682 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
683 stream_block);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000684
David Horstmannceeaeb92023-01-05 15:44:23 +0000685 for (i = 16; i > 0; i--) {
686 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +0000687 break;
David Horstmannceeaeb92023-01-05 15:44:23 +0000688 }
689 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000690 }
691 c = *input++;
David Horstmannceeaeb92023-01-05 15:44:23 +0000692 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000693
David Horstmannceeaeb92023-01-05 15:44:23 +0000694 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000695 }
696
697 *nc_off = n;
698
David Horstmannceeaeb92023-01-05 15:44:23 +0000699 return 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000700}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701#endif /* MBEDTLS_CIPHER_MODE_CTR */
702#endif /* !MBEDTLS_CAMELLIA_ALT */
Paul Bakker38119b12009-01-10 23:31:23 +0000703
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000705
Paul Bakker38119b12009-01-10 23:31:23 +0000706/*
707 * Camellia test vectors from:
708 *
709 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
710 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
711 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000712 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000713 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000714#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000715
716static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
717{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000718 {
719 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
720 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200721 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
723 },
724 {
725 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
726 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
727 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200728 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
731 },
732 {
733 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
734 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
735 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
736 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200737 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
741 },
Paul Bakker38119b12009-01-10 23:31:23 +0000742};
743
744static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
745{
746 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
747 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200748 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
750};
751
752static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
753{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000754 {
755 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
756 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
757 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
758 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
759 },
760 {
761 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
762 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
763 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
764 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
765 },
766 {
767 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
768 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
769 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
770 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
771 }
Paul Bakker38119b12009-01-10 23:31:23 +0000772};
773
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000775#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000776
777static const unsigned char camellia_test_cbc_key[3][32] =
778{
David Horstmannceeaeb92023-01-05 15:44:23 +0000779 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
780 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000781 ,
David Horstmannceeaeb92023-01-05 15:44:23 +0000782 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
783 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
784 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000785 ,
David Horstmannceeaeb92023-01-05 15:44:23 +0000786 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
787 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
788 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
789 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000790};
791
792static const unsigned char camellia_test_cbc_iv[16] =
793
David Horstmannceeaeb92023-01-05 15:44:23 +0000794{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
795 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Paul Bakker38119b12009-01-10 23:31:23 +0000796;
797
798static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
799{
800 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
801 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
802 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
803 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
804 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
805 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
806
807};
808
809static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
810{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000811 {
812 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
813 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
814 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
815 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
816 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
817 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
818 },
819 {
820 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
821 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
822 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
823 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
824 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
825 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
826 },
827 {
828 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
829 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
830 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
831 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
832 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
833 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
834 }
Paul Bakker38119b12009-01-10 23:31:23 +0000835};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000839/*
840 * Camellia-CTR test vectors from:
841 *
842 * http://www.faqs.org/rfcs/rfc5528.html
843 */
844
845static const unsigned char camellia_test_ctr_key[3][16] =
846{
847 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
848 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
849 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
850 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
851 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
852 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
853};
854
855static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
856{
857 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
859 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
860 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
861 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
862 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
863};
864
865static const unsigned char camellia_test_ctr_pt[3][48] =
866{
867 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
868 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
869
870 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
871 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
872 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
873 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
874
875 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
876 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
877 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
878 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
879 0x20, 0x21, 0x22, 0x23 }
880};
881
882static const unsigned char camellia_test_ctr_ct[3][48] =
883{
884 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
885 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
886 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
887 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
888 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
889 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
890 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
891 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
892 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
893 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
894 0xDF, 0x50, 0x86, 0x96 }
895};
896
897static const int camellia_test_ctr_len[3] =
David Horstmannceeaeb92023-01-05 15:44:23 +0000898{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000900
901/*
902 * Checkup routine
903 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000904int mbedtls_camellia_self_test(int verbose)
Paul Bakker38119b12009-01-10 23:31:23 +0000905{
Paul Bakker026c03b2009-03-28 17:53:03 +0000906 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000907 unsigned char key[32];
908 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000909 unsigned char src[16];
910 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000912 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200913#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000915 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000916 unsigned char nonce_counter[16];
917 unsigned char stream_block[16];
918#endif
Gilles Peskine66c616a2021-05-25 09:17:46 +0200919 int ret = 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000922
David Horstmannceeaeb92023-01-05 15:44:23 +0000923 mbedtls_camellia_init(&ctx);
924 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000925
David Horstmannceeaeb92023-01-05 15:44:23 +0000926 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000927 u = j >> 1;
David Horstmannceeaeb92023-01-05 15:44:23 +0000928 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000929
David Horstmannceeaeb92023-01-05 15:44:23 +0000930 if (verbose != 0) {
931 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
932 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000933 }
Paul Bakker38119b12009-01-10 23:31:23 +0000934
David Horstmannceeaeb92023-01-05 15:44:23 +0000935 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
936 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000937
David Horstmannceeaeb92023-01-05 15:44:23 +0000938 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
939 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
940 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
941 memcpy(dst, camellia_test_ecb_plain[i], 16);
942 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
943 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
944 memcpy(src, camellia_test_ecb_plain[i], 16);
945 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
946 }
947
948 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
949
950 if (memcmp(buf, dst, 16) != 0) {
951 if (verbose != 0) {
952 mbedtls_printf("failed\n");
953 }
954 goto exit;
955 }
956 }
957
958 if (verbose != 0) {
959 mbedtls_printf("passed\n");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000960 }
961 }
Paul Bakker38119b12009-01-10 23:31:23 +0000962
David Horstmannceeaeb92023-01-05 15:44:23 +0000963 if (verbose != 0) {
964 mbedtls_printf("\n");
Paul Bakker38119b12009-01-10 23:31:23 +0000965 }
966
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000968 /*
969 * CBC mode
970 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000971 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000972 u = j >> 1;
973 v = j & 1;
974
David Horstmannceeaeb92023-01-05 15:44:23 +0000975 if (verbose != 0) {
976 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
977 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000978 }
Paul Bakker38119b12009-01-10 23:31:23 +0000979
David Horstmannceeaeb92023-01-05 15:44:23 +0000980 memcpy(src, camellia_test_cbc_iv, 16);
981 memcpy(dst, camellia_test_cbc_iv, 16);
982 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000983
David Horstmannceeaeb92023-01-05 15:44:23 +0000984 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
985 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
986 } else {
987 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
988 }
989
990 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
991
992 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
993 memcpy(iv, src, 16);
994 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
995 memcpy(dst, camellia_test_cbc_plain[i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100996 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
David Horstmannceeaeb92023-01-05 15:44:23 +0000997 memcpy(iv, dst, 16);
998 memcpy(src, camellia_test_cbc_plain[i], 16);
999 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +01001000 }
Paul Bakker38119b12009-01-10 23:31:23 +00001001
David Horstmannceeaeb92023-01-05 15:44:23 +00001002 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +01001003
David Horstmannceeaeb92023-01-05 15:44:23 +00001004 if (memcmp(buf, dst, 16) != 0) {
1005 if (verbose != 0) {
1006 mbedtls_printf("failed\n");
1007 }
Gilles Peskine66c616a2021-05-25 09:17:46 +02001008 goto exit;
Janos Follath98e28a72016-05-31 14:03:54 +01001009 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +00001010 }
Paul Bakker38119b12009-01-10 23:31:23 +00001011
David Horstmannceeaeb92023-01-05 15:44:23 +00001012 if (verbose != 0) {
1013 mbedtls_printf("passed\n");
1014 }
Paul Bakker38119b12009-01-10 23:31:23 +00001015 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +00001017
David Horstmannceeaeb92023-01-05 15:44:23 +00001018 if (verbose != 0) {
1019 mbedtls_printf("\n");
1020 }
Paul Bakker38119b12009-01-10 23:31:23 +00001021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001023 /*
1024 * CTR mode
1025 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001026 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001027 u = i >> 1;
1028 v = i & 1;
1029
David Horstmannceeaeb92023-01-05 15:44:23 +00001030 if (verbose != 0) {
1031 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
1032 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1033 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001034
David Horstmannceeaeb92023-01-05 15:44:23 +00001035 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1036 memcpy(key, camellia_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001037
1038 offset = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +00001039 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001040
David Horstmannceeaeb92023-01-05 15:44:23 +00001041 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001042 len = camellia_test_ctr_len[u];
David Horstmannceeaeb92023-01-05 15:44:23 +00001043 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001044
David Horstmannceeaeb92023-01-05 15:44:23 +00001045 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1046 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001047
David Horstmannceeaeb92023-01-05 15:44:23 +00001048 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1049 if (verbose != 0) {
1050 mbedtls_printf("failed\n");
1051 }
Gilles Peskine66c616a2021-05-25 09:17:46 +02001052 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001053 }
David Horstmannceeaeb92023-01-05 15:44:23 +00001054 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001055 len = camellia_test_ctr_len[u];
David Horstmannceeaeb92023-01-05 15:44:23 +00001056 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001057
David Horstmannceeaeb92023-01-05 15:44:23 +00001058 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1059 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001060
David Horstmannceeaeb92023-01-05 15:44:23 +00001061 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1062 if (verbose != 0) {
1063 mbedtls_printf("failed\n");
1064 }
Gilles Peskine66c616a2021-05-25 09:17:46 +02001065 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001066 }
1067 }
1068
David Horstmannceeaeb92023-01-05 15:44:23 +00001069 if (verbose != 0) {
1070 mbedtls_printf("passed\n");
1071 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001072 }
1073
David Horstmannceeaeb92023-01-05 15:44:23 +00001074 if (verbose != 0) {
1075 mbedtls_printf("\n");
1076 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001078
Gilles Peskine66c616a2021-05-25 09:17:46 +02001079 ret = 0;
1080
1081exit:
David Horstmannceeaeb92023-01-05 15:44:23 +00001082 mbedtls_camellia_free(&ctx);
1083 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +00001084}
1085
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001087
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088#endif /* MBEDTLS_CAMELLIA_C */