blob: bd76ea874f7f2b308d5b3b9bc6c4473bdb601501 [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 Rodgman7ff79652023-11-03 12:04:52 +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
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050027/* Parameter validation macros */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010028#define CAMELLIA_VALIDATE_RET(cond) \
29 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
30#define CAMELLIA_VALIDATE(cond) \
31 MBEDTLS_INTERNAL_VALIDATE(cond)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050032
Paul Bakker38119b12009-01-10 23:31:23 +000033static const unsigned char SIGMA_CHARS[6][8] =
34{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000035 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
36 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
37 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
38 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
39 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
40 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +000041};
42
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
Paul Bakkerfa049db2009-01-12 22:12:03 +000044
45static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +000046{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010047 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
48 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
49 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
50 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
51 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
52 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
53 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
54 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
55 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
56 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
57 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
58 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
59 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
60 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
61 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
62 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakker38119b12009-01-10 23:31:23 +000063};
64
65#define SBOX1(n) FSb[(n)]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
67#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +000068#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +000071
Paul Bakkerc32c6b52009-01-11 21:36:43 +000072static const unsigned char FSb[256] =
73{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010074 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
75 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
76 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
77 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
78 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
79 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
80 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
81 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
82 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
83 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
84 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
85 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
86 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
87 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
88 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
89 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +000090};
91
92static const unsigned char FSb2[256] =
93{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010094 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
95 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
96 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
97 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
98 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
99 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
100 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
101 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
102 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
103 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
104 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
105 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
106 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
107 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
108 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
109 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000110};
111
112static const unsigned char FSb3[256] =
113{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100114 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
115 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
116 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
117 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
118 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
119 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
120 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
121 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
122 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
123 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
124 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
125 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
126 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
127 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
128 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
129 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000130};
131
132static const unsigned char FSb4[256] =
133{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
135 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
136 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
137 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
138 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
139 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
140 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
141 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
142 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
143 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
144 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
145 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
146 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
147 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
148 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
149 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000150};
151
152#define SBOX1(n) FSb[(n)]
153#define SBOX2(n) FSb2[(n)]
154#define SBOX3(n) FSb3[(n)]
155#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
Paul Bakkerfa049db2009-01-12 22:12:03 +0000158
Paul Bakker38119b12009-01-10 23:31:23 +0000159static const unsigned char shifts[2][4][4] =
160{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000161 {
162 { 1, 1, 1, 1 }, /* KL */
163 { 0, 0, 0, 0 }, /* KR */
164 { 1, 1, 1, 1 }, /* KA */
165 { 0, 0, 0, 0 } /* KB */
166 },
167 {
168 { 1, 0, 1, 1 }, /* KL */
169 { 1, 1, 0, 1 }, /* KR */
170 { 1, 1, 1, 0 }, /* KA */
171 { 1, 1, 0, 1 } /* KB */
172 }
Paul Bakker38119b12009-01-10 23:31:23 +0000173};
174
Paul Bakker026c03b2009-03-28 17:53:03 +0000175static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000176{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000177 {
178 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000180 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
181 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
182 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100183 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000184 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
185 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
186 },
187 {
188 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100189 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000190 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
191 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
192 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
193 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
194 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100195 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000196 }
Paul Bakker38119b12009-01-10 23:31:23 +0000197};
198
Paul Bakker026c03b2009-03-28 17:53:03 +0000199static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000200{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000201 {
202 21, 22, 23, 20,
203 -1, -1, -1, -1,
204 18, 19, 16, 17,
205 11, 8, 9, 10,
206 15, 12, 13, 14
207 },
208 {
209 25, 26, 27, 24,
210 29, 30, 31, 28,
211 18, 19, 16, 17,
212 -1, -1, -1, -1,
213 -1, -1, -1, -1
214 }
Paul Bakker38119b12009-01-10 23:31:23 +0000215};
216
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000217/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000218#define ROTL(DEST, SRC, SHIFT) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100219 { \
220 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
221 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
222 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
223 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
224 }
Paul Bakker38119b12009-01-10 23:31:23 +0000225
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000226#define FL(XL, XR, KL, KR) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227 { \
228 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
229 (XL) = ((XR) | (KR)) ^ (XL); \
230 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200231
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000232#define FLInv(YL, YR, KL, KR) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100233 { \
234 (YL) = ((YR) | (KR)) ^ (YL); \
235 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
236 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200237
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000238#define SHIFT_AND_PLACE(INDEX, OFFSET) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 { \
240 TK[0] = KC[(OFFSET) * 4 + 0]; \
241 TK[1] = KC[(OFFSET) * 4 + 1]; \
242 TK[2] = KC[(OFFSET) * 4 + 2]; \
243 TK[3] = KC[(OFFSET) * 4 + 3]; \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000244 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245 for (i = 1; i <= 4; i++) \
246 if (shifts[(INDEX)][(OFFSET)][i -1]) \
247 ROTL(TK + i * 4, TK, (15 * i) % 32); \
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000248 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100249 for (i = 0; i < 20; i++) \
250 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
251 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
Paul Bakker66d5d072014-06-17 16:39:18 +0200252 } \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253 }
Paul Bakker38119b12009-01-10 23:31:23 +0000254
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100255static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
256 uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000257{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000258 uint32_t I0, I1;
259 I0 = x[0] ^ k[0];
260 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100262 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
263 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
264 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
265 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
266 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
267 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
268 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
269 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
Paul Bakker38119b12009-01-10 23:31:23 +0000270
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000271 I0 ^= (I1 << 8) | (I1 >> 24);
272 I1 ^= (I0 << 16) | (I0 >> 16);
273 I0 ^= (I1 >> 8) | (I1 << 24);
274 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000275
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000276 z[0] ^= I1;
277 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000278}
279
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200281{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282 CAMELLIA_VALIDATE(ctx != NULL);
283 memset(ctx, 0, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200284}
285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100290 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200293}
294
Paul Bakker38119b12009-01-10 23:31:23 +0000295/*
296 * Camellia key schedule (encryption)
297 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
299 const unsigned char *key,
300 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000301{
Paul Bakker23986e52011-04-24 08:57:21 +0000302 int idx;
303 size_t i;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000304 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000305 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000306 uint32_t SIGMA[6][2];
307 uint32_t KC[16];
308 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310 CAMELLIA_VALIDATE_RET(ctx != NULL);
311 CAMELLIA_VALIDATE_RET(key != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500312
Paul Bakker38119b12009-01-10 23:31:23 +0000313 RK = ctx->rk;
314
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315 memset(t, 0, 64);
316 memset(RK, 0, sizeof(ctx->rk));
Paul Bakker38119b12009-01-10 23:31:23 +0000317
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 switch (keybits) {
Paul Bakker38119b12009-01-10 23:31:23 +0000319 case 128: ctx->nr = 3; idx = 0; break;
320 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000321 case 256: ctx->nr = 4; idx = 1; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
Paul Bakker38119b12009-01-10 23:31:23 +0000323 }
324
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325 for (i = 0; i < keybits / 8; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000326 t[i] = key[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327 }
Paul Bakker38119b12009-01-10 23:31:23 +0000328
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100329 if (keybits == 192) {
330 for (i = 0; i < 8; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000331 t[24 + i] = ~t[16 + i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100332 }
Paul Bakker38119b12009-01-10 23:31:23 +0000333 }
334
Paul Bakker38119b12009-01-10 23:31:23 +0000335 /*
336 * Prepare SIGMA values
337 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 for (i = 0; i < 6; i++) {
339 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
340 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000341 }
342
343 /*
344 * Key storage in KC
345 * Order: KL, KR, KA, KB
346 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347 memset(KC, 0, sizeof(KC));
Paul Bakker38119b12009-01-10 23:31:23 +0000348
349 /* Store KL, KR */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100350 for (i = 0; i < 8; i++) {
351 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
352 }
Paul Bakker38119b12009-01-10 23:31:23 +0000353
354 /* Generate KA */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000356 KC[8 + i] = KC[i] ^ KC[4 + i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100357 }
Paul Bakker38119b12009-01-10 23:31:23 +0000358
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100359 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
360 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000363 KC[8 + i] ^= KC[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100364 }
Paul Bakker38119b12009-01-10 23:31:23 +0000365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
367 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
Paul Bakker38119b12009-01-10 23:31:23 +0000368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 if (keybits > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000370 /* Generate KB */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100371 for (i = 0; i < 4; ++i) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000372 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 }
Paul Bakker38119b12009-01-10 23:31:23 +0000374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100375 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
376 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000377 }
378
379 /*
380 * Generating subkeys
Paul Bakker9af723c2014-05-01 13:03:14 +0200381 */
Paul Bakker38119b12009-01-10 23:31:23 +0000382
383 /* Manipulating KL */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100384 SHIFT_AND_PLACE(idx, 0);
Paul Bakker38119b12009-01-10 23:31:23 +0000385
386 /* Manipulating KR */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 if (keybits > 128) {
388 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000389 }
390
391 /* Manipulating KA */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100392 SHIFT_AND_PLACE(idx, 2);
Paul Bakker38119b12009-01-10 23:31:23 +0000393
394 /* Manipulating KB */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 if (keybits > 128) {
396 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000397 }
398
399 /* Do transpositions */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 for (i = 0; i < 20; i++) {
401 if (transposes[idx][i] != -1) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000402 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
403 }
Paul Bakker38119b12009-01-10 23:31:23 +0000404 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000405
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100406 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000407}
408
409/*
410 * Camellia key schedule (decryption)
411 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
413 const unsigned char *key,
414 unsigned int keybits)
Paul Bakker38119b12009-01-10 23:31:23 +0000415{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200416 int idx, ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000417 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 mbedtls_camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000419 uint32_t *RK;
420 uint32_t *SK;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100421 CAMELLIA_VALIDATE_RET(ctx != NULL);
422 CAMELLIA_VALIDATE_RET(key != NULL);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200423
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100424 mbedtls_camellia_init(&cty);
Paul Bakker38119b12009-01-10 23:31:23 +0000425
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200426 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100427 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200428 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 }
Paul Bakker38119b12009-01-10 23:31:23 +0000430
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200431 ctx->nr = cty.nr;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100432 idx = (ctx->nr == 4);
Manuel Pégourié-Gonnard3ac6a2b2014-05-28 22:04:25 +0200433
434 RK = ctx->rk;
Paul Bakker38119b12009-01-10 23:31:23 +0000435 SK = cty.rk + 24 * 2 + 8 * idx * 2;
436
437 *RK++ = *SK++;
438 *RK++ = *SK++;
439 *RK++ = *SK++;
440 *RK++ = *SK++;
441
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000443 *RK++ = *SK++;
444 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000445 }
446
447 SK -= 2;
448
449 *RK++ = *SK++;
450 *RK++ = *SK++;
451 *RK++ = *SK++;
452 *RK++ = *SK++;
453
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200454exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100455 mbedtls_camellia_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000456
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100457 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000458}
459
460/*
461 * Camellia-ECB block encryption/decryption
462 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100463int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
464 int mode,
465 const unsigned char input[16],
466 unsigned char output[16])
Paul Bakker38119b12009-01-10 23:31:23 +0000467{
Paul Bakker026c03b2009-03-28 17:53:03 +0000468 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000469 uint32_t *RK, X[4];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100470 CAMELLIA_VALIDATE_RET(ctx != NULL);
471 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
472 mode == MBEDTLS_CAMELLIA_DECRYPT);
473 CAMELLIA_VALIDATE_RET(input != NULL);
474 CAMELLIA_VALIDATE_RET(output != NULL);
Paul Bakker38119b12009-01-10 23:31:23 +0000475
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100476 ((void) mode);
Paul Bakkerc2547b02009-07-20 20:40:52 +0000477
Paul Bakker38119b12009-01-10 23:31:23 +0000478 NR = ctx->nr;
479 RK = ctx->rk;
480
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100481 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
482 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
483 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
484 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000485
486 X[0] ^= *RK++;
487 X[1] ^= *RK++;
488 X[2] ^= *RK++;
489 X[3] ^= *RK++;
490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000492 --NR;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100493 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000494 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100495 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000496 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000498 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100499 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000500 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100501 camellia_feistel(X, RK, X + 2);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000502 RK += 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100503 camellia_feistel(X + 2, RK, X);
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000504 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 if (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000507 FL(X[0], X[1], RK[0], RK[1]);
508 RK += 2;
509 FLInv(X[2], X[3], RK[0], RK[1]);
510 RK += 2;
511 }
Paul Bakker38119b12009-01-10 23:31:23 +0000512 }
513
514 X[2] ^= *RK++;
515 X[3] ^= *RK++;
516 X[0] ^= *RK++;
517 X[1] ^= *RK++;
518
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100519 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
520 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
521 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
522 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000523
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100524 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000525}
526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000528/*
529 * Camellia-CBC buffer encryption/decryption
530 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
532 int mode,
533 size_t length,
534 unsigned char iv[16],
535 const unsigned char *input,
536 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000537{
538 int i;
539 unsigned char temp[16];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100540 CAMELLIA_VALIDATE_RET(ctx != NULL);
541 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
542 mode == MBEDTLS_CAMELLIA_DECRYPT);
543 CAMELLIA_VALIDATE_RET(iv != NULL);
544 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
545 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
Paul Bakker38119b12009-01-10 23:31:23 +0000546
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100547 if (length % 16) {
548 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
549 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000550
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100551 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
552 while (length > 0) {
553 memcpy(temp, input, 16);
554 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
Paul Bakker38119b12009-01-10 23:31:23 +0000555
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100556 for (i = 0; i < 16; i++) {
557 output[i] = (unsigned char) (output[i] ^ iv[i]);
558 }
Paul Bakker38119b12009-01-10 23:31:23 +0000559
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100560 memcpy(iv, temp, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000561
562 input += 16;
563 output += 16;
564 length -= 16;
565 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100566 } else {
567 while (length > 0) {
568 for (i = 0; i < 16; i++) {
569 output[i] = (unsigned char) (input[i] ^ iv[i]);
570 }
Paul Bakker38119b12009-01-10 23:31:23 +0000571
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100572 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
573 memcpy(iv, output, 16);
Paul Bakker38119b12009-01-10 23:31:23 +0000574
575 input += 16;
576 output += 16;
577 length -= 16;
578 }
579 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000580
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100581 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000582}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker38119b12009-01-10 23:31:23 +0000586/*
587 * Camellia-CFB128 buffer encryption/decryption
588 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100589int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
590 int mode,
591 size_t length,
592 size_t *iv_off,
593 unsigned char iv[16],
594 const unsigned char *input,
595 unsigned char *output)
Paul Bakker38119b12009-01-10 23:31:23 +0000596{
Paul Bakker1ef71df2011-06-09 14:14:58 +0000597 int c;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500598 size_t n;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100599 CAMELLIA_VALIDATE_RET(ctx != NULL);
600 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
601 mode == MBEDTLS_CAMELLIA_DECRYPT);
602 CAMELLIA_VALIDATE_RET(iv != NULL);
603 CAMELLIA_VALIDATE_RET(iv_off != NULL);
604 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
605 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500606
607 n = *iv_off;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 if (n >= 16) {
609 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
610 }
Paul Bakker38119b12009-01-10 23:31:23 +0000611
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100612 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
613 while (length--) {
614 if (n == 0) {
615 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
616 }
Paul Bakker38119b12009-01-10 23:31:23 +0000617
618 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100619 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker38119b12009-01-10 23:31:23 +0000620 iv[n] = (unsigned char) c;
621
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100622 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000623 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 } else {
625 while (length--) {
626 if (n == 0) {
627 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
628 }
Paul Bakker38119b12009-01-10 23:31:23 +0000629
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker38119b12009-01-10 23:31:23 +0000631
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100632 n = (n + 1) & 0x0F;
Paul Bakker38119b12009-01-10 23:31:23 +0000633 }
634 }
635
636 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000637
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100638 return 0;
Paul Bakker38119b12009-01-10 23:31:23 +0000639}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000641
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000643/*
644 * Camellia-CTR buffer encryption/decryption
645 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100646int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
647 size_t length,
648 size_t *nc_off,
649 unsigned char nonce_counter[16],
650 unsigned char stream_block[16],
651 const unsigned char *input,
652 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000653{
Paul Bakker369e14b2012-04-18 14:16:09 +0000654 int c, i;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500655 size_t n;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656 CAMELLIA_VALIDATE_RET(ctx != NULL);
657 CAMELLIA_VALIDATE_RET(nonce_counter != NULL);
658 CAMELLIA_VALIDATE_RET(stream_block != NULL);
659 CAMELLIA_VALIDATE_RET(nc_off != NULL);
660 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
661 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500662
663 n = *nc_off;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100664 if (n >= 16) {
665 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
666 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000667
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100668 while (length--) {
669 if (n == 0) {
670 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
671 stream_block);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000672
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100673 for (i = 16; i > 0; i--) {
674 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +0000675 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100676 }
677 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000678 }
679 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100680 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000681
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100682 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000683 }
684
685 *nc_off = n;
686
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100687 return 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000688}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689#endif /* MBEDTLS_CIPHER_MODE_CTR */
690#endif /* !MBEDTLS_CAMELLIA_ALT */
Paul Bakker38119b12009-01-10 23:31:23 +0000691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692#if defined(MBEDTLS_SELF_TEST)
Paul Bakker38119b12009-01-10 23:31:23 +0000693
Paul Bakker38119b12009-01-10 23:31:23 +0000694/*
695 * Camellia test vectors from:
696 *
697 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
698 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
699 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000700 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000701 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000702#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000703
704static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
705{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000706 {
707 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
708 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200709 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
711 },
712 {
713 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
714 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
715 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200716 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
719 },
720 {
721 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
722 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
723 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
724 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
Paul Bakker9af723c2014-05-01 13:03:14 +0200725 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
729 },
Paul Bakker38119b12009-01-10 23:31:23 +0000730};
731
732static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
733{
734 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
735 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
Paul Bakker9af723c2014-05-01 13:03:14 +0200736 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
Paul Bakker38119b12009-01-10 23:31:23 +0000737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
738};
739
740static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
741{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000742 {
743 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
744 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
745 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
746 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
747 },
748 {
749 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
750 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
751 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
752 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
753 },
754 {
755 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
756 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
757 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
758 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
759 }
Paul Bakker38119b12009-01-10 23:31:23 +0000760};
761
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000763#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000764
765static const unsigned char camellia_test_cbc_key[3][32] =
766{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100767 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
768 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000769 ,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100770 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
771 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
772 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000773 ,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100774 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
775 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
776 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
777 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000778};
779
780static const unsigned char camellia_test_cbc_iv[16] =
781
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100782{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
783 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
Paul Bakker38119b12009-01-10 23:31:23 +0000784;
785
786static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
787{
788 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
789 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
790 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
791 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
792 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
793 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
794
795};
796
797static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
798{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000799 {
800 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
801 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
802 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
803 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
804 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
805 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
806 },
807 {
808 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
809 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
810 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
811 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
812 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
813 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
814 },
815 {
816 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
817 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
818 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
819 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
820 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
821 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
822 }
Paul Bakker38119b12009-01-10 23:31:23 +0000823};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +0000825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000827/*
828 * Camellia-CTR test vectors from:
829 *
830 * http://www.faqs.org/rfcs/rfc5528.html
831 */
832
833static const unsigned char camellia_test_ctr_key[3][16] =
834{
835 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
836 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
837 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
838 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
839 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
840 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
841};
842
843static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
844{
845 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
847 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
848 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
849 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
850 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
851};
852
853static const unsigned char camellia_test_ctr_pt[3][48] =
854{
855 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
856 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
857
858 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
859 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
860 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
861 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
862
863 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
864 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
865 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
866 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
867 0x20, 0x21, 0x22, 0x23 }
868};
869
870static const unsigned char camellia_test_ctr_ct[3][48] =
871{
872 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
873 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
874 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
875 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
876 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
877 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
878 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
879 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
880 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
881 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
882 0xDF, 0x50, 0x86, 0x96 }
883};
884
885static const int camellia_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100886{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker38119b12009-01-10 23:31:23 +0000888
889/*
890 * Checkup routine
891 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892int mbedtls_camellia_self_test(int verbose)
Paul Bakker38119b12009-01-10 23:31:23 +0000893{
Paul Bakker026c03b2009-03-28 17:53:03 +0000894 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000895 unsigned char key[32];
896 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000897 unsigned char src[16];
898 unsigned char dst[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000900 unsigned char iv[16];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200901#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakker1ef71df2011-06-09 14:14:58 +0000903 size_t offset, len;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000904 unsigned char nonce_counter[16];
905 unsigned char stream_block[16];
906#endif
Gilles Peskine66c616a2021-05-25 09:17:46 +0200907 int ret = 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +0000908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 mbedtls_camellia_context ctx;
Paul Bakker38119b12009-01-10 23:31:23 +0000910
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100911 mbedtls_camellia_init(&ctx);
912 memset(key, 0, 32);
Paul Bakker38119b12009-01-10 23:31:23 +0000913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000915 u = j >> 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000917
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100918 if (verbose != 0) {
919 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
920 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000921 }
Paul Bakker38119b12009-01-10 23:31:23 +0000922
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
924 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000925
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100926 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
927 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
928 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
929 memcpy(dst, camellia_test_ecb_plain[i], 16);
930 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
931 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
932 memcpy(src, camellia_test_ecb_plain[i], 16);
933 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
934 }
935
936 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
937
938 if (memcmp(buf, dst, 16) != 0) {
939 if (verbose != 0) {
940 mbedtls_printf("failed\n");
941 }
942 goto exit;
943 }
944 }
945
946 if (verbose != 0) {
947 mbedtls_printf("passed\n");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000948 }
949 }
Paul Bakker38119b12009-01-10 23:31:23 +0000950
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100951 if (verbose != 0) {
952 mbedtls_printf("\n");
Paul Bakker38119b12009-01-10 23:31:23 +0000953 }
954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker38119b12009-01-10 23:31:23 +0000956 /*
957 * CBC mode
958 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100959 for (j = 0; j < 6; j++) {
Paul Bakker38119b12009-01-10 23:31:23 +0000960 u = j >> 1;
961 v = j & 1;
962
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100963 if (verbose != 0) {
964 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
965 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000966 }
Paul Bakker38119b12009-01-10 23:31:23 +0000967
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100968 memcpy(src, camellia_test_cbc_iv, 16);
969 memcpy(dst, camellia_test_cbc_iv, 16);
970 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000971
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100972 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
973 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
974 } else {
975 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
976 }
977
978 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
979
980 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
981 memcpy(iv, src, 16);
982 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
983 memcpy(dst, camellia_test_cbc_plain[i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100984 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100985 memcpy(iv, dst, 16);
986 memcpy(src, camellia_test_cbc_plain[i], 16);
987 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
Janos Follath98e28a72016-05-31 14:03:54 +0100988 }
Paul Bakker38119b12009-01-10 23:31:23 +0000989
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100990 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Janos Follath98e28a72016-05-31 14:03:54 +0100991
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100992 if (memcmp(buf, dst, 16) != 0) {
993 if (verbose != 0) {
994 mbedtls_printf("failed\n");
995 }
Gilles Peskine66c616a2021-05-25 09:17:46 +0200996 goto exit;
Janos Follath98e28a72016-05-31 14:03:54 +0100997 }
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000998 }
Paul Bakker38119b12009-01-10 23:31:23 +0000999
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000 if (verbose != 0) {
1001 mbedtls_printf("passed\n");
1002 }
Paul Bakker38119b12009-01-10 23:31:23 +00001003 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker38119b12009-01-10 23:31:23 +00001005
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001006 if (verbose != 0) {
1007 mbedtls_printf("\n");
1008 }
Paul Bakker38119b12009-01-10 23:31:23 +00001009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001011 /*
1012 * CTR mode
1013 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001014 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001015 u = i >> 1;
1016 v = i & 1;
1017
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001018 if (verbose != 0) {
1019 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
1020 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1021 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001022
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001023 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1024 memcpy(key, camellia_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001025
1026 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001027 mbedtls_camellia_setkey_enc(&ctx, key, 128);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001028
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001029 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001030 len = camellia_test_ctr_len[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001031 memcpy(buf, camellia_test_ctr_ct[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001032
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001033 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1034 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001035
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001036 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1037 if (verbose != 0) {
1038 mbedtls_printf("failed\n");
1039 }
Gilles Peskine66c616a2021-05-25 09:17:46 +02001040 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001041 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001042 } else {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001043 len = camellia_test_ctr_len[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001044 memcpy(buf, camellia_test_ctr_pt[u], len);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001045
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001046 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1047 buf, buf);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001048
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001049 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1050 if (verbose != 0) {
1051 mbedtls_printf("failed\n");
1052 }
Gilles Peskine66c616a2021-05-25 09:17:46 +02001053 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001054 }
1055 }
1056
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001057 if (verbose != 0) {
1058 mbedtls_printf("passed\n");
1059 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001060 }
1061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001062 if (verbose != 0) {
1063 mbedtls_printf("\n");
1064 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001066
Gilles Peskine66c616a2021-05-25 09:17:46 +02001067 ret = 0;
1068
1069exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001070 mbedtls_camellia_free(&ctx);
1071 return ret;
Paul Bakker38119b12009-01-10 23:31:23 +00001072}
1073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074#endif /* MBEDTLS_SELF_TEST */
Paul Bakker38119b12009-01-10 23:31:23 +00001075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076#endif /* MBEDTLS_CAMELLIA_C */