blob: b1c0a08ca23ab020e37e91c1c2f7cebf8dab0fda [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker38119b12009-01-10 23:31:23 +00006 */
7/*
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +00008 * The Camellia block cipher was designed by NTT and Mitsubishi Electric
9 * Corporation.
Paul Bakker38119b12009-01-10 23:31:23 +000010 *
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000011 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
Paul Bakker38119b12009-01-10 23:31:23 +000012 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Paul Bakker38119b12009-01-10 23:31:23 +000015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_CAMELLIA_C)
Paul Bakker38119b12009-01-10 23:31:23 +000017
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000018#include "mbedtls/camellia.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050019#include "mbedtls/platform_util.h"
Paul Bakker38119b12009-01-10 23:31:23 +000020
Rich Evans00ab4702015-02-06 13:43:58 +000021#include <string.h>
Manuel Pégourié-Gonnard394608e2015-02-17 16:01:07 +010022
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025#if !defined(MBEDTLS_CAMELLIA_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020026
Paul Bakker38119b12009-01-10 23:31:23 +000027static const unsigned char SIGMA_CHARS[6][8] =
28{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000029 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
30 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
31 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
32 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
33 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
34 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +000035};
36
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
Paul Bakkerfa049db2009-01-12 22:12:03 +000038
39static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +000040{
Gilles Peskine449bd832023-01-11 14:50:10 +010041 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
42 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
43 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
44 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
45 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
46 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
47 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
48 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
49 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
50 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
51 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
52 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
53 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
54 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
55 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
56 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakker38119b12009-01-10 23:31:23 +000057};
58
59#define SBOX1(n) FSb[(n)]
Gilles Peskine449bd832023-01-11 14:50:10 +010060#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
61#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +000062#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
63
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +000065
Paul Bakkerc32c6b52009-01-11 21:36:43 +000066static const unsigned char FSb[256] =
67{
Gilles Peskine449bd832023-01-11 14:50:10 +010068 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
69 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
70 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
71 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
72 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
73 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
74 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
75 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
76 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
77 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
78 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
79 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
80 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
81 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
82 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
83 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +000084};
85
86static const unsigned char FSb2[256] =
87{
Gilles Peskine449bd832023-01-11 14:50:10 +010088 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
89 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
90 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
91 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
92 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
93 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
94 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
95 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
96 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
97 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
98 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
99 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
100 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
101 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
102 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
103 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000104};
105
106static const unsigned char FSb3[256] =
107{
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
109 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
110 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
111 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
112 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
113 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
114 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
115 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
116 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
117 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
118 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
119 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
120 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
121 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
122 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
123 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000124};
125
126static const unsigned char FSb4[256] =
127{
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
129 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
130 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
131 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
132 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
133 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
134 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
135 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
136 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
137 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
138 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
139 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
140 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
141 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
142 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
143 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000144};
145
146#define SBOX1(n) FSb[(n)]
147#define SBOX2(n) FSb2[(n)]
148#define SBOX3(n) FSb3[(n)]
149#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000152
Paul Bakker38119b12009-01-10 23:31:23 +0000153static const unsigned char shifts[2][4][4] =
154{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000155 {
156 { 1, 1, 1, 1 }, /* KL */
157 { 0, 0, 0, 0 }, /* KR */
158 { 1, 1, 1, 1 }, /* KA */
159 { 0, 0, 0, 0 } /* KB */
160 },
161 {
162 { 1, 0, 1, 1 }, /* KL */
163 { 1, 1, 0, 1 }, /* KR */
164 { 1, 1, 1, 0 }, /* KA */
165 { 1, 1, 0, 1 } /* KB */
166 }
Paul Bakker38119b12009-01-10 23:31:23 +0000167};
168
Paul Bakker026c03b2009-03-28 17:53:03 +0000169static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000170{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000171 {
172 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000174 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
175 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
176 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000178 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
179 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
180 },
181 {
182 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000184 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
185 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
186 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
187 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
188 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000190 }
Paul Bakker38119b12009-01-10 23:31:23 +0000191};
192
Paul Bakker026c03b2009-03-28 17:53:03 +0000193static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000194{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000195 {
196 21, 22, 23, 20,
197 -1, -1, -1, -1,
198 18, 19, 16, 17,
199 11, 8, 9, 10,
200 15, 12, 13, 14
201 },
202 {
203 25, 26, 27, 24,
204 29, 30, 31, 28,
205 18, 19, 16, 17,
206 -1, -1, -1, -1,
207 -1, -1, -1, -1
208 }
Paul Bakker38119b12009-01-10 23:31:23 +0000209};
210
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000211/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000212#define ROTL(DEST, SRC, SHIFT) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 { \
214 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
215 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
216 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
217 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
218 }
Paul Bakker38119b12009-01-10 23:31:23 +0000219
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000220#define FL(XL, XR, KL, KR) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 { \
222 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
223 (XL) = ((XR) | (KR)) ^ (XL); \
224 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200225
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000226#define FLInv(YL, YR, KL, KR) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 { \
228 (YL) = ((YR) | (KR)) ^ (YL); \
229 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
230 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200231
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000232#define SHIFT_AND_PLACE(INDEX, OFFSET) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 { \
234 TK[0] = KC[(OFFSET) * 4 + 0]; \
235 TK[1] = KC[(OFFSET) * 4 + 1]; \
236 TK[2] = KC[(OFFSET) * 4 + 2]; \
237 TK[3] = KC[(OFFSET) * 4 + 3]; \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000238 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 for (i = 1; i <= 4; i++) \
240 if (shifts[(INDEX)][(OFFSET)][i -1]) \
241 ROTL(TK + i * 4, TK, (15 * i) % 32); \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000242 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 for (i = 0; i < 20; i++) \
244 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
245 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
Paul Bakker66d5d072014-06-17 16:39:18 +0200246 } \
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 }
Paul Bakker38119b12009-01-10 23:31:23 +0000248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
250 uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000251{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000252 uint32_t I0, I1;
253 I0 = x[0] ^ k[0];
254 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
257 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
258 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
259 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
260 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
261 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
262 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
263 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
Paul Bakker38119b12009-01-10 23:31:23 +0000264
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000265 I0 ^= (I1 << 8) | (I1 >> 24);
266 I1 ^= (I0 << 16) | (I0 >> 16);
267 I0 ^= (I1 >> 8) | (I1 << 24);
268 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000269
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000270 z[0] ^= I1;
271 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000272}
273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200275{
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200277}
278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280{
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200282 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200286}
287
Paul Bakker38119b12009-01-10 23:31:23 +0000288/*
289 * Camellia key schedule (encryption)
290 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100291int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
292 const unsigned char *key,
293 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000294{
Paul Bakker23986e52011-04-24 08:57:21 +0000295 int idx;
296 size_t i;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000297 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000298 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000299 uint32_t SIGMA[6][2];
300 uint32_t KC[16];
301 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000302
303 RK = ctx->rk;
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 memset(t, 0, 64);
306 memset(RK, 0, sizeof(ctx->rk));
Paul Bakker38119b12009-01-10 23:31:23 +0000307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 switch (keybits) {
Paul Bakker38119b12009-01-10 23:31:23 +0000309 case 128: ctx->nr = 3; idx = 0; break;
310 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000311 case 256: ctx->nr = 4; idx = 1; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Paul Bakker38119b12009-01-10 23:31:23 +0000313 }
314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 for (i = 0; i < keybits / 8; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000316 t[i] = key[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 }
Paul Bakker38119b12009-01-10 23:31:23 +0000318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 if (keybits == 192) {
320 for (i = 0; i < 8; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000321 t[24 + i] = ~t[16 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 }
Paul Bakker38119b12009-01-10 23:31:23 +0000323 }
324
Paul Bakker38119b12009-01-10 23:31:23 +0000325 /*
326 * Prepare SIGMA values
327 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 for (i = 0; i < 6; i++) {
329 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
330 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000331 }
332
333 /*
334 * Key storage in KC
335 * Order: KL, KR, KA, KB
336 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 memset(KC, 0, sizeof(KC));
Paul Bakker38119b12009-01-10 23:31:23 +0000338
339 /* Store KL, KR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 for (i = 0; i < 8; i++) {
341 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
342 }
Paul Bakker38119b12009-01-10 23:31:23 +0000343
344 /* Generate KA */
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000346 KC[8 + i] = KC[i] ^ KC[4 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 }
Paul Bakker38119b12009-01-10 23:31:23 +0000348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
350 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000353 KC[8 + i] ^= KC[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 }
Paul Bakker38119b12009-01-10 23:31:23 +0000355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
357 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 if (keybits > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000360 /* Generate KB */
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000362 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 }
Paul Bakker38119b12009-01-10 23:31:23 +0000364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
366 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000367 }
368
369 /*
370 * Generating subkeys
Paul Bakker9af723c2014-05-01 13:03:14 +0200371 */
Paul Bakker38119b12009-01-10 23:31:23 +0000372
373 /* Manipulating KL */
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 SHIFT_AND_PLACE(idx, 0);
Paul Bakker38119b12009-01-10 23:31:23 +0000375
376 /* Manipulating KR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 if (keybits > 128) {
378 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000379 }
380
381 /* Manipulating KA */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 SHIFT_AND_PLACE(idx, 2);
Paul Bakker38119b12009-01-10 23:31:23 +0000383
384 /* Manipulating KB */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 if (keybits > 128) {
386 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000387 }
388
389 /* Do transpositions */
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 for (i = 0; i < 20; i++) {
391 if (transposes[idx][i] != -1) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000392 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
393 }
Paul Bakker38119b12009-01-10 23:31:23 +0000394 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000397}
398
399/*
400 * Camellia key schedule (decryption)
401 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800402#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100403int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
404 const unsigned char *key,
405 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000406{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200407 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000408 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000410 uint32_t *RK;
411 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 mbedtls_camellia_init(&cty);
Paul Bakker38119b12009-01-10 23:31:23 +0000414
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200415 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200417 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 }
Paul Bakker38119b12009-01-10 23:31:23 +0000419
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200420 ctx->nr = cty.nr;
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 idx = (ctx->nr == 4);
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200422
423 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000424 SK = cty.rk + 24 * 2 + 8 * idx * 2;
425
426 *RK++ = *SK++;
427 *RK++ = *SK++;
428 *RK++ = *SK++;
429 *RK++ = *SK++;
430
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000432 *RK++ = *SK++;
433 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000434 }
435
436 SK -= 2;
437
438 *RK++ = *SK++;
439 *RK++ = *SK++;
440 *RK++ = *SK++;
441 *RK++ = *SK++;
442
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200443exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000447}
Yanray Wangb67b4742023-10-31 17:10:32 +0800448#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Paul Bakker38119b12009-01-10 23:31:23 +0000449
450/*
451 * Camellia-ECB block encryption/decryption
452 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100453int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
454 int mode,
455 const unsigned char input[16],
456 unsigned char output[16])
Paul Bakker38119b12009-01-10 23:31:23 +0000457{
Paul Bakker026c03b2009-03-28 17:53:03 +0000458 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000459 uint32_t *RK, X[4];
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100461 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 }
Paul Bakker38119b12009-01-10 23:31:23 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 ((void) mode);
Paul Bakkerc2547b02009-07-20 20:40:52 +0000465
Paul Bakker38119b12009-01-10 23:31:23 +0000466 NR = ctx->nr;
467 RK = ctx->rk;
468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
470 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
471 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
472 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000473
474 X[0] ^= *RK++;
475 X[1] ^= *RK++;
476 X[2] ^= *RK++;
477 X[3] ^= *RK++;
478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000480 --NR;
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000482 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000484 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000486 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000488 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000490 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000492 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 if (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000495 FL(X[0], X[1], RK[0], RK[1]);
496 RK += 2;
497 FLInv(X[2], X[3], RK[0], RK[1]);
498 RK += 2;
499 }
Paul Bakker38119b12009-01-10 23:31:23 +0000500 }
501
502 X[2] ^= *RK++;
503 X[3] ^= *RK++;
504 X[0] ^= *RK++;
505 X[1] ^= *RK++;
506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
508 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
509 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
510 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000513}
514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000516/*
517 * Camellia-CBC buffer encryption/decryption
518 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100519int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
520 int mode,
521 size_t length,
522 unsigned char iv[16],
523 const unsigned char *input,
524 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000525{
Paul Bakker38119b12009-01-10 23:31:23 +0000526 unsigned char temp[16];
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100528 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 }
Paul Bakker38119b12009-01-10 23:31:23 +0000530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 if (length % 16) {
532 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
533 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
536 while (length > 0) {
537 memcpy(temp, input, 16);
538 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
Paul Bakker38119b12009-01-10 23:31:23 +0000539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 mbedtls_xor(output, output, iv, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 memcpy(iv, temp, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000543
544 input += 16;
545 output += 16;
546 length -= 16;
547 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 } else {
549 while (length > 0) {
550 mbedtls_xor(output, input, iv, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
553 memcpy(iv, output, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000554
555 input += 16;
556 output += 16;
557 length -= 16;
558 }
559 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000562}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000564
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker38119b12009-01-10 23:31:23 +0000566/*
567 * Camellia-CFB128 buffer encryption/decryption
568 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100569int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
570 int mode,
571 size_t length,
572 size_t *iv_off,
573 unsigned char iv[16],
574 const unsigned char *input,
575 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000576{
Paul Bakker1ef71df2011-06-09 14:14:58 +0000577 int c;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500578 size_t n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100580 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500582
583 n = *iv_off;
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 if (n >= 16) {
585 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
586 }
Paul Bakker38119b12009-01-10 23:31:23 +0000587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
589 while (length--) {
590 if (n == 0) {
591 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
592 }
Paul Bakker38119b12009-01-10 23:31:23 +0000593
594 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker38119b12009-01-10 23:31:23 +0000596 iv[n] = (unsigned char) c;
597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000599 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 } else {
601 while (length--) {
602 if (n == 0) {
603 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
604 }
Paul Bakker38119b12009-01-10 23:31:23 +0000605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker38119b12009-01-10 23:31:23 +0000607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000609 }
610 }
611
612 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000615}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000617
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000619/*
620 * Camellia-CTR buffer encryption/decryption
621 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100622int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
623 size_t length,
624 size_t *nc_off,
625 unsigned char nonce_counter[16],
626 unsigned char stream_block[16],
627 const unsigned char *input,
628 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000629{
Paul Bakker369e14b2012-04-18 14:16:09 +0000630 int c, i;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500631 size_t n;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500632
633 n = *nc_off;
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (n >= 16) {
635 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
636 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 while (length--) {
639 if (n == 0) {
640 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
641 stream_block);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 for (i = 16; i > 0; i--) {
644 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +0000645 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 }
647 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000648 }
649 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000653 }
654
655 *nc_off = n;
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 return 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000658}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#endif /* MBEDTLS_CIPHER_MODE_CTR */
660#endif /* !MBEDTLS_CAMELLIA_ALT */
Paul Bakker38119b12009-01-10 23:31:23 +0000661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000663
Paul Bakker38119b12009-01-10 23:31:23 +0000664/*
665 * Camellia test vectors from:
666 *
667 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
668 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
669 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000670 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000671 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000672#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000673
674static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
675{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000676 {
677 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
678 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200679 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
681 },
682 {
683 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
684 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
685 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200686 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
689 },
690 {
691 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
692 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
693 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
694 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200695 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
699 },
Paul Bakker38119b12009-01-10 23:31:23 +0000700};
701
702static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
703{
704 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
705 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200706 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
708};
709
710static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
711{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000712 {
713 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
714 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
715 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
716 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
717 },
718 {
719 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
720 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
721 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
722 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
723 },
724 {
725 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
726 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
727 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
728 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
729 }
Paul Bakker38119b12009-01-10 23:31:23 +0000730};
731
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000733#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000734
735static const unsigned char camellia_test_cbc_key[3][32] =
736{
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
738 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000739 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
741 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
742 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000743 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
745 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
746 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
747 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000748};
749
750static const unsigned char camellia_test_cbc_iv[16] =
751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
753 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Paul Bakker38119b12009-01-10 23:31:23 +0000754;
755
756static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
757{
758 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
759 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
760 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
761 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
762 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
763 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
764
765};
766
767static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
768{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000769 {
770 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
771 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
772 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
773 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
774 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
775 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
776 },
777 {
778 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
779 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
780 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
781 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
782 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
783 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
784 },
785 {
786 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
787 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
788 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
789 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
790 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
791 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
792 }
Paul Bakker38119b12009-01-10 23:31:23 +0000793};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000797/*
798 * Camellia-CTR test vectors from:
799 *
800 * http://www.faqs.org/rfcs/rfc5528.html
801 */
802
803static const unsigned char camellia_test_ctr_key[3][16] =
804{
805 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
806 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
807 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
808 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
809 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
810 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
811};
812
813static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
814{
815 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
817 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
818 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
819 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
820 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
821};
822
823static const unsigned char camellia_test_ctr_pt[3][48] =
824{
825 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
826 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
827
828 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
829 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
830 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
831 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
832
833 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
834 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
835 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
836 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
837 0x20, 0x21, 0x22, 0x23 }
838};
839
840static const unsigned char camellia_test_ctr_ct[3][48] =
841{
842 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
843 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
844 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
845 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
846 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
847 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
848 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
849 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
850 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
851 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
852 0xDF, 0x50, 0x86, 0x96 }
853};
854
855static const int camellia_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100856{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000858
859/*
860 * Checkup routine
861 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100862int mbedtls_camellia_self_test(int verbose)
Paul Bakker38119b12009-01-10 23:31:23 +0000863{
Paul Bakker026c03b2009-03-28 17:53:03 +0000864 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000865 unsigned char key[32];
866 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000867 unsigned char src[16];
868 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000870 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200871#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000873 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000874 unsigned char nonce_counter[16];
875 unsigned char stream_block[16];
876#endif
Gilles Peskinec537aa82021-05-25 09:17:46 +0200877 int ret = 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000878
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 mbedtls_camellia_init(&ctx);
882 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000885 u = j >> 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000887
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 if (verbose != 0) {
889 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
890 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000891 }
Paul Bakker38119b12009-01-10 23:31:23 +0000892
Yanray Wangb67b4742023-10-31 17:10:32 +0800893#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang9141ad12023-08-24 14:53:16 +0800894 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
895 if (verbose != 0) {
896 mbedtls_printf("skipped\n");
897 }
898 continue;
899 }
900#endif
901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
903 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000904
Yanray Wangb67b4742023-10-31 17:10:32 +0800905#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
907 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
908 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
909 memcpy(dst, camellia_test_ecb_plain[i], 16);
Yanray Wang9141ad12023-08-24 14:53:16 +0800910 } else
911#endif
912 { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
914 memcpy(src, camellia_test_ecb_plain[i], 16);
915 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
916 }
917
918 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
919
920 if (memcmp(buf, dst, 16) != 0) {
921 if (verbose != 0) {
922 mbedtls_printf("failed\n");
923 }
924 goto exit;
925 }
926 }
927
928 if (verbose != 0) {
929 mbedtls_printf("passed\n");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000930 }
931 }
Paul Bakker38119b12009-01-10 23:31:23 +0000932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 if (verbose != 0) {
934 mbedtls_printf("\n");
Paul Bakker38119b12009-01-10 23:31:23 +0000935 }
936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000938 /*
939 * CBC mode
940 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000942 u = j >> 1;
943 v = j & 1;
944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 if (verbose != 0) {
946 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
947 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000948 }
Paul Bakker38119b12009-01-10 23:31:23 +0000949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 memcpy(src, camellia_test_cbc_iv, 16);
951 memcpy(dst, camellia_test_cbc_iv, 16);
952 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
955 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
956 } else {
957 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
958 }
959
960 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
961
962 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
963 memcpy(iv, src, 16);
964 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
965 memcpy(dst, camellia_test_cbc_plain[i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100966 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 memcpy(iv, dst, 16);
968 memcpy(src, camellia_test_cbc_plain[i], 16);
969 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100970 }
Paul Bakker38119b12009-01-10 23:31:23 +0000971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +0100973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 if (memcmp(buf, dst, 16) != 0) {
975 if (verbose != 0) {
976 mbedtls_printf("failed\n");
977 }
Gilles Peskinec537aa82021-05-25 09:17:46 +0200978 goto exit;
Janos Follath98e28a72016-05-31 14:03:54 +0100979 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000980 }
Paul Bakker38119b12009-01-10 23:31:23 +0000981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 if (verbose != 0) {
983 mbedtls_printf("passed\n");
984 }
Paul Bakker38119b12009-01-10 23:31:23 +0000985 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 if (verbose != 0) {
989 mbedtls_printf("\n");
990 }
Paul Bakker38119b12009-01-10 23:31:23 +0000991
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000993 /*
994 * CTR mode
995 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000997 u = i >> 1;
998 v = i & 1;
999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 if (verbose != 0) {
1001 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
1002 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1003 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1006 memcpy(key, camellia_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001007
1008 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001012 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1016 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1019 if (verbose != 0) {
1020 mbedtls_printf("failed\n");
1021 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001022 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001023 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001025 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1029 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1032 if (verbose != 0) {
1033 mbedtls_printf("failed\n");
1034 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001035 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001036 }
1037 }
1038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 if (verbose != 0) {
1040 mbedtls_printf("passed\n");
1041 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001042 }
1043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 if (verbose != 0) {
1045 mbedtls_printf("\n");
1046 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001048
Gilles Peskinec537aa82021-05-25 09:17:46 +02001049 ret = 0;
1050
1051exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 mbedtls_camellia_free(&ctx);
1053 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +00001054}
1055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058#endif /* MBEDTLS_CAMELLIA_C */