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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010040#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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010059 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)]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010078#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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010086 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100146 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100191 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100195 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100201 -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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100207 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) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100231 { \
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) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 { \
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) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245 { \
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) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100251 { \
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 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 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 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100261 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 } \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 }
Paul Bakker38119b12009-01-10 23:31:23 +0000266
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267static 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200293{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100294 CAMELLIA_VALIDATE(ctx != NULL);
295 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200296}
297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200299{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200301 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100302 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100304 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310int 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327 memset(t, 0, 64);
328 memset(RK, 0, sizeof(ctx->rk));
Paul Bakker38119b12009-01-10 23:31:23 +0000329
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100330 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Paul Bakker38119b12009-01-10 23:31:23 +0000335 }
336
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 for (i = 0; i < keybits / 8; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000338 t[i] = key[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100339 }
Paul Bakker38119b12009-01-10 23:31:23 +0000340
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100341 if (keybits == 192) {
342 for (i = 0; i < 8; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000343 t[24 + i] = ~t[16 + i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100344 }
Paul Bakker38119b12009-01-10 23:31:23 +0000345 }
346
Paul Bakker38119b12009-01-10 23:31:23 +0000347 /*
348 * Prepare SIGMA values
349 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100350 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100359 memset(KC, 0, sizeof(KC));
Paul Bakker38119b12009-01-10 23:31:23 +0000360
361 /* Store KL, KR */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000368 KC[8 + i] = KC[i] ^ KC[4 + i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 }
Paul Bakker38119b12009-01-10 23:31:23 +0000370
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100371 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000375 KC[8 + i] ^= KC[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100376 }
Paul Bakker38119b12009-01-10 23:31:23 +0000377
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 if (keybits > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000382 /* Generate KB */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000384 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 }
Paul Bakker38119b12009-01-10 23:31:23 +0000386
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100396 SHIFT_AND_PLACE(idx, 0);
Paul Bakker38119b12009-01-10 23:31:23 +0000397
398 /* Manipulating KR */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100399 if (keybits > 128) {
400 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000401 }
402
403 /* Manipulating KA */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 SHIFT_AND_PLACE(idx, 2);
Paul Bakker38119b12009-01-10 23:31:23 +0000405
406 /* Manipulating KB */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100407 if (keybits > 128) {
408 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000409 }
410
411 /* Do transpositions */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000419}
420
421/*
422 * Camellia key schedule (decryption)
423 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100424int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 CAMELLIA_VALIDATE_RET(ctx != NULL);
434 CAMELLIA_VALIDATE_RET(key != NULL);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200435
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100436 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100439 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200440 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100441 }
Paul Bakker38119b12009-01-10 23:31:23 +0000442
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200443 ctx->nr = cty.nr;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100444 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 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:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100467 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000468
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100469 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000470}
471
472/*
473 * Camellia-ECB block encryption/decryption
474 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100475int 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];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100482 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100488 ((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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100493 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100503 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000504 --NR;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100505 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000506 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100507 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000508 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000510 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100511 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000512 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100513 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000514 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100515 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000516 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100543int 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];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100552 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100559 if (length % 16) {
560 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
561 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000562
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100563 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100568 for (i = 0; i < 16; i++) {
569 output[i] = (unsigned char) (output[i] ^ iv[i]);
570 }
Paul Bakker38119b12009-01-10 23:31:23 +0000571
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100572 memcpy(iv, temp, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000573
574 input += 16;
575 output += 16;
576 length -= 16;
577 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100578 } 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100584 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100593 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100601int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100611 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100620 if (n >= 16) {
621 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
622 }
Paul Bakker38119b12009-01-10 23:31:23 +0000623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 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++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100631 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker38119b12009-01-10 23:31:23 +0000632 iv[n] = (unsigned char) c;
633
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100634 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000635 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100636 } 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100642 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker38119b12009-01-10 23:31:23 +0000643
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100644 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100650 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100658int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100668 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100676 if (n >= 16) {
677 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
678 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000679
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100680 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100685 for (i = 16; i > 0; i--) {
686 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +0000687 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100688 }
689 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000690 }
691 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100692 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000693
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100694 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000695 }
696
697 *nc_off = n;
698
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100699 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100779 { 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 ,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100782 { 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 ,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100786 { 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794{ 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] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100898{ 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904int 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 mbedtls_camellia_init(&ctx);
924 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000925
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100926 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000927 u = j >> 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100928 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000929
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100930 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100935 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100938 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100963 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100971 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000972 u = j >> 1;
973 v = j & 1;
974
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100975 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100980 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100984 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100997 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001002 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +01001003
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001004 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001012 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001018 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001026 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001027 u = i >> 1;
1028 v = i & 1;
1029
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001030 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001035 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001039 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001040
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001041 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001042 len = camellia_test_ctr_len[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001043 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001044
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001045 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1046 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001047
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001048 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 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001054 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001055 len = camellia_test_ctr_len[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001056 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001057
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001058 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1059 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001060
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001061 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001069 if (verbose != 0) {
1070 mbedtls_printf("passed\n");
1071 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001072 }
1073
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001074 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:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001082 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 */