blob: d863699f192bab4b6ba855c124e94bf5a82f5166 [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
Paul Bakker38119b12009-01-10 23:31:23 +000025static const unsigned char SIGMA_CHARS[6][8] =
26{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000027 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
28 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
29 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
30 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
31 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
32 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +000033};
34
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
Paul Bakkerfa049db2009-01-12 22:12:03 +000036
37static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +000038{
Gilles Peskine449bd832023-01-11 14:50:10 +010039 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
40 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
41 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
42 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
43 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
44 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
45 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
46 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
47 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
48 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
49 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
50 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
51 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
52 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
53 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
54 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakker38119b12009-01-10 23:31:23 +000055};
56
57#define SBOX1(n) FSb[(n)]
Gilles Peskine449bd832023-01-11 14:50:10 +010058#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
59#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +000060#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
61
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +000063
Paul Bakkerc32c6b52009-01-11 21:36:43 +000064static const unsigned char FSb[256] =
65{
Gilles Peskine449bd832023-01-11 14:50:10 +010066 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
67 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
68 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
69 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
70 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
71 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
72 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
73 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
74 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
75 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
76 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
77 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
78 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
79 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
80 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
81 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +000082};
83
84static const unsigned char FSb2[256] =
85{
Gilles Peskine449bd832023-01-11 14:50:10 +010086 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
87 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
88 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
89 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
90 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
91 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
92 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
93 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
94 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
95 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
96 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
97 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
98 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
99 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
100 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
101 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000102};
103
104static const unsigned char FSb3[256] =
105{
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
107 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
108 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
109 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
110 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
111 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
112 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
113 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
114 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
115 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
116 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
117 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
118 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
119 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
120 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
121 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000122};
123
124static const unsigned char FSb4[256] =
125{
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
127 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
128 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
129 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
130 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
131 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
132 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
133 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
134 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
135 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
136 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
137 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
138 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
139 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
140 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
141 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000142};
143
144#define SBOX1(n) FSb[(n)]
145#define SBOX2(n) FSb2[(n)]
146#define SBOX3(n) FSb3[(n)]
147#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000150
Paul Bakker38119b12009-01-10 23:31:23 +0000151static const unsigned char shifts[2][4][4] =
152{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000153 {
154 { 1, 1, 1, 1 }, /* KL */
155 { 0, 0, 0, 0 }, /* KR */
156 { 1, 1, 1, 1 }, /* KA */
157 { 0, 0, 0, 0 } /* KB */
158 },
159 {
160 { 1, 0, 1, 1 }, /* KL */
161 { 1, 1, 0, 1 }, /* KR */
162 { 1, 1, 1, 0 }, /* KA */
163 { 1, 1, 0, 1 } /* KB */
164 }
Paul Bakker38119b12009-01-10 23:31:23 +0000165};
166
Paul Bakker026c03b2009-03-28 17:53:03 +0000167static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000168{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000169 {
170 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000172 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
173 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
174 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000176 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
177 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
178 },
179 {
180 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000182 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
183 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
184 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
185 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
186 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000188 }
Paul Bakker38119b12009-01-10 23:31:23 +0000189};
190
Paul Bakker026c03b2009-03-28 17:53:03 +0000191static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000192{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000193 {
194 21, 22, 23, 20,
195 -1, -1, -1, -1,
196 18, 19, 16, 17,
197 11, 8, 9, 10,
198 15, 12, 13, 14
199 },
200 {
201 25, 26, 27, 24,
202 29, 30, 31, 28,
203 18, 19, 16, 17,
204 -1, -1, -1, -1,
205 -1, -1, -1, -1
206 }
Paul Bakker38119b12009-01-10 23:31:23 +0000207};
208
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000209/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000210#define ROTL(DEST, SRC, SHIFT) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 { \
212 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
213 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
214 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
215 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
216 }
Paul Bakker38119b12009-01-10 23:31:23 +0000217
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000218#define FL(XL, XR, KL, KR) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 { \
220 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
221 (XL) = ((XR) | (KR)) ^ (XL); \
222 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200223
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000224#define FLInv(YL, YR, KL, KR) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 { \
226 (YL) = ((YR) | (KR)) ^ (YL); \
227 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
228 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200229
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000230#define SHIFT_AND_PLACE(INDEX, OFFSET) \
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 { \
232 TK[0] = KC[(OFFSET) * 4 + 0]; \
233 TK[1] = KC[(OFFSET) * 4 + 1]; \
234 TK[2] = KC[(OFFSET) * 4 + 2]; \
235 TK[3] = KC[(OFFSET) * 4 + 3]; \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000236 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 for (i = 1; i <= 4; i++) \
238 if (shifts[(INDEX)][(OFFSET)][i -1]) \
239 ROTL(TK + i * 4, TK, (15 * i) % 32); \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000240 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 for (i = 0; i < 20; i++) \
242 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
243 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
Paul Bakker66d5d072014-06-17 16:39:18 +0200244 } \
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 }
Paul Bakker38119b12009-01-10 23:31:23 +0000246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
248 uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000249{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000250 uint32_t I0, I1;
251 I0 = x[0] ^ k[0];
252 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
255 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
256 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
257 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
258 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
259 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
260 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
261 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
Paul Bakker38119b12009-01-10 23:31:23 +0000262
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000263 I0 ^= (I1 << 8) | (I1 >> 24);
264 I1 ^= (I0 << 16) | (I0 >> 16);
265 I0 ^= (I1 >> 8) | (I1 << 24);
266 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000267
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000268 z[0] ^= I1;
269 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000270}
271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200273{
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200275}
276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200278{
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200284}
285
Paul Bakker38119b12009-01-10 23:31:23 +0000286/*
287 * Camellia key schedule (encryption)
288 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100289int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
290 const unsigned char *key,
291 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000292{
Paul Bakker23986e52011-04-24 08:57:21 +0000293 int idx;
294 size_t i;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000295 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000296 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000297 uint32_t SIGMA[6][2];
298 uint32_t KC[16];
299 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000300
301 RK = ctx->rk;
302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 memset(t, 0, 64);
304 memset(RK, 0, sizeof(ctx->rk));
Paul Bakker38119b12009-01-10 23:31:23 +0000305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 switch (keybits) {
Paul Bakker38119b12009-01-10 23:31:23 +0000307 case 128: ctx->nr = 3; idx = 0; break;
308 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000309 case 256: ctx->nr = 4; idx = 1; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Paul Bakker38119b12009-01-10 23:31:23 +0000311 }
312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 for (i = 0; i < keybits / 8; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000314 t[i] = key[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 }
Paul Bakker38119b12009-01-10 23:31:23 +0000316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 if (keybits == 192) {
318 for (i = 0; i < 8; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000319 t[24 + i] = ~t[16 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 }
Paul Bakker38119b12009-01-10 23:31:23 +0000321 }
322
Paul Bakker38119b12009-01-10 23:31:23 +0000323 /*
324 * Prepare SIGMA values
325 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 for (i = 0; i < 6; i++) {
327 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
328 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000329 }
330
331 /*
332 * Key storage in KC
333 * Order: KL, KR, KA, KB
334 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 memset(KC, 0, sizeof(KC));
Paul Bakker38119b12009-01-10 23:31:23 +0000336
337 /* Store KL, KR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 for (i = 0; i < 8; i++) {
339 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
340 }
Paul Bakker38119b12009-01-10 23:31:23 +0000341
342 /* Generate KA */
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000344 KC[8 + i] = KC[i] ^ KC[4 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 }
Paul Bakker38119b12009-01-10 23:31:23 +0000346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
348 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000351 KC[8 + i] ^= KC[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 }
Paul Bakker38119b12009-01-10 23:31:23 +0000353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
355 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 if (keybits > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000358 /* Generate KB */
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000360 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 }
Paul Bakker38119b12009-01-10 23:31:23 +0000362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
364 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000365 }
366
367 /*
368 * Generating subkeys
Paul Bakker9af723c2014-05-01 13:03:14 +0200369 */
Paul Bakker38119b12009-01-10 23:31:23 +0000370
371 /* Manipulating KL */
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 SHIFT_AND_PLACE(idx, 0);
Paul Bakker38119b12009-01-10 23:31:23 +0000373
374 /* Manipulating KR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 if (keybits > 128) {
376 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000377 }
378
379 /* Manipulating KA */
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 SHIFT_AND_PLACE(idx, 2);
Paul Bakker38119b12009-01-10 23:31:23 +0000381
382 /* Manipulating KB */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 if (keybits > 128) {
384 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000385 }
386
387 /* Do transpositions */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 for (i = 0; i < 20; i++) {
389 if (transposes[idx][i] != -1) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000390 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
391 }
Paul Bakker38119b12009-01-10 23:31:23 +0000392 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000395}
396
397/*
398 * Camellia key schedule (decryption)
399 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800400#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100401int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
402 const unsigned char *key,
403 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000404{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200405 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000406 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000408 uint32_t *RK;
409 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 mbedtls_camellia_init(&cty);
Paul Bakker38119b12009-01-10 23:31:23 +0000412
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200413 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200415 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 }
Paul Bakker38119b12009-01-10 23:31:23 +0000417
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200418 ctx->nr = cty.nr;
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 idx = (ctx->nr == 4);
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200420
421 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000422 SK = cty.rk + 24 * 2 + 8 * idx * 2;
423
424 *RK++ = *SK++;
425 *RK++ = *SK++;
426 *RK++ = *SK++;
427 *RK++ = *SK++;
428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000430 *RK++ = *SK++;
431 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000432 }
433
434 SK -= 2;
435
436 *RK++ = *SK++;
437 *RK++ = *SK++;
438 *RK++ = *SK++;
439 *RK++ = *SK++;
440
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200441exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000445}
Yanray Wangb67b4742023-10-31 17:10:32 +0800446#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Paul Bakker38119b12009-01-10 23:31:23 +0000447
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 */
Paul Bakker38119b12009-01-10 23:31:23 +0000658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000660
Paul Bakker38119b12009-01-10 23:31:23 +0000661/*
662 * Camellia test vectors from:
663 *
664 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
665 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
666 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000667 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000668 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000669#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000670
671static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
672{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000673 {
674 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
675 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200676 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
678 },
679 {
680 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
681 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
682 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200683 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
686 },
687 {
688 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
689 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
690 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
691 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200692 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
696 },
Paul Bakker38119b12009-01-10 23:31:23 +0000697};
698
699static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
700{
701 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
702 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200703 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
705};
706
707static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
708{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000709 {
710 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
711 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
712 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
713 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
714 },
715 {
716 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
717 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
718 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
719 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
720 },
721 {
722 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
723 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
724 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
725 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
726 }
Paul Bakker38119b12009-01-10 23:31:23 +0000727};
728
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200729#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000730#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000731
732static const unsigned char camellia_test_cbc_key[3][32] =
733{
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
735 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000736 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
738 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
739 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000740 ,
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
742 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
743 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
744 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000745};
746
747static const unsigned char camellia_test_cbc_iv[16] =
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
750 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Paul Bakker38119b12009-01-10 23:31:23 +0000751;
752
753static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
754{
755 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
756 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
757 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
758 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
759 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
760 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
761
762};
763
764static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
765{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000766 {
767 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
768 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
769 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
770 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
771 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
772 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
773 },
774 {
775 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
776 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
777 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
778 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
779 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
780 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
781 },
782 {
783 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
784 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
785 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
786 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
787 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
788 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
789 }
Paul Bakker38119b12009-01-10 23:31:23 +0000790};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000792
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000794/*
795 * Camellia-CTR test vectors from:
796 *
797 * http://www.faqs.org/rfcs/rfc5528.html
798 */
799
800static const unsigned char camellia_test_ctr_key[3][16] =
801{
802 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
803 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
804 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
805 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
806 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
807 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
808};
809
810static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
811{
812 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
814 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
815 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
816 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
817 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
818};
819
820static const unsigned char camellia_test_ctr_pt[3][48] =
821{
822 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
823 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
824
825 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
826 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
827 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
828 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
829
830 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
831 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
832 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
833 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
834 0x20, 0x21, 0x22, 0x23 }
835};
836
837static const unsigned char camellia_test_ctr_ct[3][48] =
838{
839 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
840 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
841 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
842 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
843 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
844 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
845 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
846 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
847 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
848 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
849 0xDF, 0x50, 0x86, 0x96 }
850};
851
852static const int camellia_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100853{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000855
856/*
857 * Checkup routine
858 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100859int mbedtls_camellia_self_test(int verbose)
Paul Bakker38119b12009-01-10 23:31:23 +0000860{
Paul Bakker026c03b2009-03-28 17:53:03 +0000861 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000862 unsigned char key[32];
863 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000864 unsigned char src[16];
865 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000867 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200868#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000870 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000871 unsigned char nonce_counter[16];
872 unsigned char stream_block[16];
873#endif
Gilles Peskinec537aa82021-05-25 09:17:46 +0200874 int ret = 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000875
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 mbedtls_camellia_init(&ctx);
879 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000882 u = j >> 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 if (verbose != 0) {
886 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
887 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000888 }
Paul Bakker38119b12009-01-10 23:31:23 +0000889
Yanray Wangb67b4742023-10-31 17:10:32 +0800890#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang9141ad12023-08-24 14:53:16 +0800891 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
892 if (verbose != 0) {
893 mbedtls_printf("skipped\n");
894 }
895 continue;
896 }
897#endif
898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
900 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000901
Yanray Wangb67b4742023-10-31 17:10:32 +0800902#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
904 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
905 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
906 memcpy(dst, camellia_test_ecb_plain[i], 16);
Yanray Wang9141ad12023-08-24 14:53:16 +0800907 } else
908#endif
909 { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
911 memcpy(src, camellia_test_ecb_plain[i], 16);
912 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
913 }
914
915 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
916
917 if (memcmp(buf, dst, 16) != 0) {
918 if (verbose != 0) {
919 mbedtls_printf("failed\n");
920 }
921 goto exit;
922 }
923 }
924
925 if (verbose != 0) {
926 mbedtls_printf("passed\n");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000927 }
928 }
Paul Bakker38119b12009-01-10 23:31:23 +0000929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 if (verbose != 0) {
931 mbedtls_printf("\n");
Paul Bakker38119b12009-01-10 23:31:23 +0000932 }
933
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000935 /*
936 * CBC mode
937 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000939 u = j >> 1;
940 v = j & 1;
941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 if (verbose != 0) {
943 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
944 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000945 }
Paul Bakker38119b12009-01-10 23:31:23 +0000946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 memcpy(src, camellia_test_cbc_iv, 16);
948 memcpy(dst, camellia_test_cbc_iv, 16);
949 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
952 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
953 } else {
954 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
955 }
956
957 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
958
959 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
960 memcpy(iv, src, 16);
961 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
962 memcpy(dst, camellia_test_cbc_plain[i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100963 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 memcpy(iv, dst, 16);
965 memcpy(src, camellia_test_cbc_plain[i], 16);
966 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100967 }
Paul Bakker38119b12009-01-10 23:31:23 +0000968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +0100970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 if (memcmp(buf, dst, 16) != 0) {
972 if (verbose != 0) {
973 mbedtls_printf("failed\n");
974 }
Gilles Peskinec537aa82021-05-25 09:17:46 +0200975 goto exit;
Janos Follath98e28a72016-05-31 14:03:54 +0100976 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000977 }
Paul Bakker38119b12009-01-10 23:31:23 +0000978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if (verbose != 0) {
980 mbedtls_printf("passed\n");
981 }
Paul Bakker38119b12009-01-10 23:31:23 +0000982 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 if (verbose != 0) {
986 mbedtls_printf("\n");
987 }
Paul Bakker38119b12009-01-10 23:31:23 +0000988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000990 /*
991 * CTR mode
992 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000994 u = i >> 1;
995 v = i & 1;
996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 if (verbose != 0) {
998 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
999 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1000 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1003 memcpy(key, camellia_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001004
1005 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001009 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1013 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1016 if (verbose != 0) {
1017 mbedtls_printf("failed\n");
1018 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001019 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001020 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001022 len = camellia_test_ctr_len[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1026 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1029 if (verbose != 0) {
1030 mbedtls_printf("failed\n");
1031 }
Gilles Peskinec537aa82021-05-25 09:17:46 +02001032 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001033 }
1034 }
1035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 if (verbose != 0) {
1037 mbedtls_printf("passed\n");
1038 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001039 }
1040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 if (verbose != 0) {
1042 mbedtls_printf("\n");
1043 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001045
Gilles Peskinec537aa82021-05-25 09:17:46 +02001046 ret = 0;
1047
1048exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 mbedtls_camellia_free(&ctx);
1050 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +00001051}
1052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#endif /* MBEDTLS_CAMELLIA_C */