blob: 86c8bbfcded1211a3a61b13f15b4e237e7a2d4a9 [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 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
403 const unsigned char *key,
404 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000405{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200406 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000407 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000409 uint32_t *RK;
410 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 mbedtls_camellia_init(&cty);
Paul Bakker38119b12009-01-10 23:31:23 +0000413
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200414 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200416 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 }
Paul Bakker38119b12009-01-10 23:31:23 +0000418
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200419 ctx->nr = cty.nr;
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 idx = (ctx->nr == 4);
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200421
422 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000423 SK = cty.rk + 24 * 2 + 8 * idx * 2;
424
425 *RK++ = *SK++;
426 *RK++ = *SK++;
427 *RK++ = *SK++;
428 *RK++ = *SK++;
429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000431 *RK++ = *SK++;
432 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000433 }
434
435 SK -= 2;
436
437 *RK++ = *SK++;
438 *RK++ = *SK++;
439 *RK++ = *SK++;
440 *RK++ = *SK++;
441
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200442exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000446}
447
448/*
449 * Camellia-ECB block encryption/decryption
450 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
452 int mode,
453 const unsigned char input[16],
454 unsigned char output[16])
Paul Bakker38119b12009-01-10 23:31:23 +0000455{
Paul Bakker026c03b2009-03-28 17:53:03 +0000456 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000457 uint32_t *RK, X[4];
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100459 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 }
Paul Bakker38119b12009-01-10 23:31:23 +0000461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 ((void) mode);
Paul Bakkerc2547b02009-07-20 20:40:52 +0000463
Paul Bakker38119b12009-01-10 23:31:23 +0000464 NR = ctx->nr;
465 RK = ctx->rk;
466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
468 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
469 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
470 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000471
472 X[0] ^= *RK++;
473 X[1] ^= *RK++;
474 X[2] ^= *RK++;
475 X[3] ^= *RK++;
476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000478 --NR;
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000480 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000482 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000484 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000486 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000488 RK += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000490 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 if (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000493 FL(X[0], X[1], RK[0], RK[1]);
494 RK += 2;
495 FLInv(X[2], X[3], RK[0], RK[1]);
496 RK += 2;
497 }
Paul Bakker38119b12009-01-10 23:31:23 +0000498 }
499
500 X[2] ^= *RK++;
501 X[3] ^= *RK++;
502 X[0] ^= *RK++;
503 X[1] ^= *RK++;
504
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
506 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
507 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
508 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000509
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000511}
512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000514/*
515 * Camellia-CBC buffer encryption/decryption
516 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100517int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
518 int mode,
519 size_t length,
520 unsigned char iv[16],
521 const unsigned char *input,
522 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000523{
Paul Bakker38119b12009-01-10 23:31:23 +0000524 unsigned char temp[16];
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100526 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 }
Paul Bakker38119b12009-01-10 23:31:23 +0000528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (length % 16) {
530 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
531 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
534 while (length > 0) {
535 memcpy(temp, input, 16);
536 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
Paul Bakker38119b12009-01-10 23:31:23 +0000537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 mbedtls_xor(output, output, iv, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 memcpy(iv, temp, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000541
542 input += 16;
543 output += 16;
544 length -= 16;
545 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 } else {
547 while (length > 0) {
548 mbedtls_xor(output, input, iv, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
551 memcpy(iv, output, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000552
553 input += 16;
554 output += 16;
555 length -= 16;
556 }
557 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000560}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker38119b12009-01-10 23:31:23 +0000564/*
565 * Camellia-CFB128 buffer encryption/decryption
566 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100567int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
568 int mode,
569 size_t length,
570 size_t *iv_off,
571 unsigned char iv[16],
572 const unsigned char *input,
573 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000574{
Paul Bakker1ef71df2011-06-09 14:14:58 +0000575 int c;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500576 size_t n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) {
Tuvshinzaya Erdenekhuu1fd7f982022-08-05 15:31:57 +0100578 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500580
581 n = *iv_off;
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 if (n >= 16) {
583 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
584 }
Paul Bakker38119b12009-01-10 23:31:23 +0000585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
587 while (length--) {
588 if (n == 0) {
589 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
590 }
Paul Bakker38119b12009-01-10 23:31:23 +0000591
592 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker38119b12009-01-10 23:31:23 +0000594 iv[n] = (unsigned char) c;
595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000597 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 } else {
599 while (length--) {
600 if (n == 0) {
601 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
602 }
Paul Bakker38119b12009-01-10 23:31:23 +0000603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker38119b12009-01-10 23:31:23 +0000605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000607 }
608 }
609
610 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000613}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000617/*
618 * Camellia-CTR buffer encryption/decryption
619 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100620int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
621 size_t length,
622 size_t *nc_off,
623 unsigned char nonce_counter[16],
624 unsigned char stream_block[16],
625 const unsigned char *input,
626 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000627{
Paul Bakker369e14b2012-04-18 14:16:09 +0000628 int c, i;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500629 size_t n;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500630
631 n = *nc_off;
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 if (n >= 16) {
633 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
634 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 while (length--) {
637 if (n == 0) {
638 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
639 stream_block);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 for (i = 16; i > 0; i--) {
642 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +0000643 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 }
645 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000646 }
647 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000651 }
652
653 *nc_off = n;
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 return 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000656}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_CIPHER_MODE_CTR */
658#endif /* !MBEDTLS_CAMELLIA_ALT */
Paul Bakker38119b12009-01-10 23:31:23 +0000659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000661
Paul Bakker38119b12009-01-10 23:31:23 +0000662/*
663 * Camellia test vectors from:
664 *
665 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
666 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
667 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000668 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000669 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000670#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000671
672static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
673{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000674 {
675 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
676 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200677 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
679 },
680 {
681 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
682 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
683 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200684 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
687 },
688 {
689 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
690 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
691 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
692 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200693 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
697 },
Paul Bakker38119b12009-01-10 23:31:23 +0000698};
699
700static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
701{
702 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
703 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200704 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
706};
707
708static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
709{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000710 {
711 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
712 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
713 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
714 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
715 },
716 {
717 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
718 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
719 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
720 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
721 },
722 {
723 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
724 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
725 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
726 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
727 }
Paul Bakker38119b12009-01-10 23:31:23 +0000728};
729
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000731#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000732
733static const unsigned char camellia_test_cbc_key[3][32] =
734{
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
736 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000737 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
739 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
740 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000741 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
743 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
744 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
745 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000746};
747
748static const unsigned char camellia_test_cbc_iv[16] =
749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
751 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Paul Bakker38119b12009-01-10 23:31:23 +0000752;
753
754static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
755{
756 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
757 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
758 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
759 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
760 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
761 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
762
763};
764
765static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
766{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000767 {
768 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
769 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
770 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
771 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
772 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
773 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
774 },
775 {
776 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
777 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
778 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
779 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
780 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
781 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
782 },
783 {
784 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
785 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
786 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
787 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
788 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
789 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
790 }
Paul Bakker38119b12009-01-10 23:31:23 +0000791};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000795/*
796 * Camellia-CTR test vectors from:
797 *
798 * http://www.faqs.org/rfcs/rfc5528.html
799 */
800
801static const unsigned char camellia_test_ctr_key[3][16] =
802{
803 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
804 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
805 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
806 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
807 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
808 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
809};
810
811static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
812{
813 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
815 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
816 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
817 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
818 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
819};
820
821static const unsigned char camellia_test_ctr_pt[3][48] =
822{
823 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
824 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
825
826 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
827 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
828 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
829 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
830
831 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
832 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
833 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
834 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
835 0x20, 0x21, 0x22, 0x23 }
836};
837
838static const unsigned char camellia_test_ctr_ct[3][48] =
839{
840 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
841 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
842 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
843 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
844 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
845 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
846 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
847 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
848 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
849 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
850 0xDF, 0x50, 0x86, 0x96 }
851};
852
853static const int camellia_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100854{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000856
857/*
858 * Checkup routine
859 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100860int mbedtls_camellia_self_test(int verbose)
Paul Bakker38119b12009-01-10 23:31:23 +0000861{
Paul Bakker026c03b2009-03-28 17:53:03 +0000862 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000863 unsigned char key[32];
864 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000865 unsigned char src[16];
866 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000868 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200869#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000871 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000872 unsigned char nonce_counter[16];
873 unsigned char stream_block[16];
874#endif
Gilles Peskinec537aa82021-05-25 09:17:46 +0200875 int ret = 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000876
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 mbedtls_camellia_init(&ctx);
880 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000883 u = j >> 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000885
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 if (verbose != 0) {
887 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
888 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000889 }
Paul Bakker38119b12009-01-10 23:31:23 +0000890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
892 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
895 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
896 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
897 memcpy(dst, camellia_test_ecb_plain[i], 16);
898 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
899 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
900 memcpy(src, camellia_test_ecb_plain[i], 16);
901 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
902 }
903
904 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
905
906 if (memcmp(buf, dst, 16) != 0) {
907 if (verbose != 0) {
908 mbedtls_printf("failed\n");
909 }
910 goto exit;
911 }
912 }
913
914 if (verbose != 0) {
915 mbedtls_printf("passed\n");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000916 }
917 }
Paul Bakker38119b12009-01-10 23:31:23 +0000918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (verbose != 0) {
920 mbedtls_printf("\n");
Paul Bakker38119b12009-01-10 23:31:23 +0000921 }
922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000924 /*
925 * CBC mode
926 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000928 u = j >> 1;
929 v = j & 1;
930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 if (verbose != 0) {
932 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
933 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000934 }
Paul Bakker38119b12009-01-10 23:31:23 +0000935
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 memcpy(src, camellia_test_cbc_iv, 16);
937 memcpy(dst, camellia_test_cbc_iv, 16);
938 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
941 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
942 } else {
943 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
944 }
945
946 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
947
948 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
949 memcpy(iv, src, 16);
950 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
951 memcpy(dst, camellia_test_cbc_plain[i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100952 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 memcpy(iv, dst, 16);
954 memcpy(src, camellia_test_cbc_plain[i], 16);
955 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100956 }
Paul Bakker38119b12009-01-10 23:31:23 +0000957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +0100959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 if (memcmp(buf, dst, 16) != 0) {
961 if (verbose != 0) {
962 mbedtls_printf("failed\n");
963 }
Gilles Peskinec537aa82021-05-25 09:17:46 +0200964 goto exit;
Janos Follath98e28a72016-05-31 14:03:54 +0100965 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000966 }
Paul Bakker38119b12009-01-10 23:31:23 +0000967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 if (verbose != 0) {
969 mbedtls_printf("passed\n");
970 }
Paul Bakker38119b12009-01-10 23:31:23 +0000971 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 if (verbose != 0) {
975 mbedtls_printf("\n");
976 }
Paul Bakker38119b12009-01-10 23:31:23 +0000977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000979 /*
980 * CTR mode
981 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000983 u = i >> 1;
984 v = i & 1;
985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 if (verbose != 0) {
987 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
988 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
989 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
992 memcpy(key, camellia_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000993
994 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000998 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1002 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1005 if (verbose != 0) {
1006 mbedtls_printf("failed\n");
1007 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001008 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001009 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001011 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1015 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1018 if (verbose != 0) {
1019 mbedtls_printf("failed\n");
1020 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001021 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001022 }
1023 }
1024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 if (verbose != 0) {
1026 mbedtls_printf("passed\n");
1027 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001028 }
1029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 if (verbose != 0) {
1031 mbedtls_printf("\n");
1032 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001034
Gilles Peskinec537aa82021-05-25 09:17:46 +02001035 ret = 0;
1036
1037exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 mbedtls_camellia_free(&ctx);
1039 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +00001040}
1041
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044#endif /* MBEDTLS_CAMELLIA_C */