3 * The CAST-128 block cipher, described in RFC 2144.
7 * Written by Steve Reid <sreid@sea-to-sky.net>
8 * 100% Public Domain - no warranty
12 /* nettle, low-level cryptographics library
14 * Copyright (C) 2001 Niels Möller
16 * The nettle library is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU Lesser General Public License as published by
18 * the Free Software Foundation; either version 2.1 of the License, or (at your
19 * option) any later version.
21 * The nettle library is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 * License for more details.
26 * You should have received a copy of the GNU Lesser General Public License
27 * along with the nettle library; see the file COPYING.LIB. If not, write to
28 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
39 #include "cast128_sboxes.h"
43 #define CAST_SMALL_KEY 10
44 #define CAST_SMALL_ROUNDS 12
45 #define CAST_FULL_ROUNDS 16
47 /* Macros to access 8-bit bytes out of a 32-bit word */
48 #define U8a(x) ( (uint8_t) (x>>24) )
49 #define U8b(x) ( (uint8_t) ((x>>16)&0xff) )
50 #define U8c(x) ( (uint8_t) ((x>>8)&0xff) )
51 #define U8d(x) ( (uint8_t) ((x)&0xff) )
53 /* CAST-128 uses three different round functions */
54 #define F1(l, r, i) do { \
55 t = ROTL32(ctx->keys[i+16], ctx->keys[i] + r); \
56 l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \
57 - cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)]; \
59 #define F2(l, r, i) do { \
60 t = ROTL32( ctx->keys[i+16], ctx->keys[i] ^ r); \
61 l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \
62 + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)]; \
64 #define F3(l, r, i) do { \
65 t = ROTL32(ctx->keys[i+16], ctx->keys[i] - r); \
66 l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \
67 ^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)]; \
71 /***** Encryption Function *****/
74 cast128_encrypt(const struct cast128_ctx
*ctx
,
75 unsigned length
, uint8_t *dst
,
78 FOR_BLOCKS(length
, dst
, src
, CAST128_BLOCK_SIZE
)
82 /* Get inblock into l,r */
84 r
= READ_UINT32(src
+4);
99 /* Only do full 16 rounds if key length > 80 bits */
100 if (ctx
->rounds
> 12) {
106 /* Put l,r into outblock */
107 WRITE_UINT32(dst
, r
);
108 WRITE_UINT32(dst
+ 4, l
);
115 /***** Decryption Function *****/
118 cast128_decrypt(const struct cast128_ctx
*ctx
,
119 unsigned length
, uint8_t *dst
,
122 FOR_BLOCKS(length
, dst
, src
, CAST128_BLOCK_SIZE
)
126 /* Get inblock into l,r */
127 r
= READ_UINT32(src
);
128 l
= READ_UINT32(src
+4);
131 /* Only do full 16 rounds if key length > 80 bits */
132 if (ctx
->rounds
> 12) {
151 /* Put l,r into outblock */
152 WRITE_UINT32(dst
, l
);
153 WRITE_UINT32(dst
+ 4, r
);
160 /***** Key Schedule *****/
163 cast128_set_key(struct cast128_ctx
*ctx
,
164 unsigned keybytes
, const uint8_t *rawkey
)
166 uint32_t t
[4], z
[4], x
[4];
169 /* Set number of rounds to 12 or 16, depending on key length */
170 ctx
->rounds
= (keybytes
<= CAST_SMALL_KEY
)
171 ? CAST_SMALL_ROUNDS
: CAST_FULL_ROUNDS
;
173 /* Copy key to workspace x */
174 for (i
= 0; i
< 4; i
++) {
176 if ((i
*4+0) < keybytes
) x
[i
] = (uint32_t)rawkey
[i
*4+0] << 24;
177 if ((i
*4+1) < keybytes
) x
[i
] |= (uint32_t)rawkey
[i
*4+1] << 16;
178 if ((i
*4+2) < keybytes
) x
[i
] |= (uint32_t)rawkey
[i
*4+2] << 8;
179 if ((i
*4+3) < keybytes
) x
[i
] |= (uint32_t)rawkey
[i
*4+3];
181 /* FIXME: For the shorter key sizes, the last 4 subkeys are not
182 used, and need not be generated, nor stored. */
183 /* Generate 32 subkeys, four at a time */
184 for (i
= 0; i
< 32; i
+=4) {
187 t
[0] = z
[0] = x
[0] ^ cast_sbox5
[U8b(x
[3])]
188 ^ cast_sbox6
[U8d(x
[3])] ^ cast_sbox7
[U8a(x
[3])]
189 ^ cast_sbox8
[U8c(x
[3])] ^ cast_sbox7
[U8a(x
[2])];
190 t
[1] = z
[1] = x
[2] ^ cast_sbox5
[U8a(z
[0])]
191 ^ cast_sbox6
[U8c(z
[0])] ^ cast_sbox7
[U8b(z
[0])]
192 ^ cast_sbox8
[U8d(z
[0])] ^ cast_sbox8
[U8c(x
[2])];
193 t
[2] = z
[2] = x
[3] ^ cast_sbox5
[U8d(z
[1])]
194 ^ cast_sbox6
[U8c(z
[1])] ^ cast_sbox7
[U8b(z
[1])]
195 ^ cast_sbox8
[U8a(z
[1])] ^ cast_sbox5
[U8b(x
[2])];
196 t
[3] = z
[3] = x
[1] ^ cast_sbox5
[U8c(z
[2])] ^
197 cast_sbox6
[U8b(z
[2])] ^ cast_sbox7
[U8d(z
[2])]
198 ^ cast_sbox8
[U8a(z
[2])] ^ cast_sbox6
[U8d(x
[2])];
201 t
[0] = x
[0] = z
[2] ^ cast_sbox5
[U8b(z
[1])]
202 ^ cast_sbox6
[U8d(z
[1])] ^ cast_sbox7
[U8a(z
[1])]
203 ^ cast_sbox8
[U8c(z
[1])] ^ cast_sbox7
[U8a(z
[0])];
204 t
[1] = x
[1] = z
[0] ^ cast_sbox5
[U8a(x
[0])]
205 ^ cast_sbox6
[U8c(x
[0])] ^ cast_sbox7
[U8b(x
[0])]
206 ^ cast_sbox8
[U8d(x
[0])] ^ cast_sbox8
[U8c(z
[0])];
207 t
[2] = x
[2] = z
[1] ^ cast_sbox5
[U8d(x
[1])]
208 ^ cast_sbox6
[U8c(x
[1])] ^ cast_sbox7
[U8b(x
[1])]
209 ^ cast_sbox8
[U8a(x
[1])] ^ cast_sbox5
[U8b(z
[0])];
210 t
[3] = x
[3] = z
[3] ^ cast_sbox5
[U8c(x
[2])]
211 ^ cast_sbox6
[U8b(x
[2])] ^ cast_sbox7
[U8d(x
[2])]
212 ^ cast_sbox8
[U8a(x
[2])] ^ cast_sbox6
[U8d(z
[0])];
218 ctx
->keys
[i
+0] = cast_sbox5
[U8a(t
[2])] ^ cast_sbox6
[U8b(t
[2])]
219 ^ cast_sbox7
[U8d(t
[1])] ^ cast_sbox8
[U8c(t
[1])];
220 ctx
->keys
[i
+1] = cast_sbox5
[U8c(t
[2])] ^ cast_sbox6
[U8d(t
[2])]
221 ^ cast_sbox7
[U8b(t
[1])] ^ cast_sbox8
[U8a(t
[1])];
222 ctx
->keys
[i
+2] = cast_sbox5
[U8a(t
[3])] ^ cast_sbox6
[U8b(t
[3])]
223 ^ cast_sbox7
[U8d(t
[0])] ^ cast_sbox8
[U8c(t
[0])];
224 ctx
->keys
[i
+3] = cast_sbox5
[U8c(t
[3])] ^ cast_sbox6
[U8d(t
[3])]
225 ^ cast_sbox7
[U8b(t
[0])] ^ cast_sbox8
[U8a(t
[0])];
229 ctx
->keys
[i
+0] = cast_sbox5
[U8d(t
[0])] ^ cast_sbox6
[U8c(t
[0])]
230 ^ cast_sbox7
[U8a(t
[3])] ^ cast_sbox8
[U8b(t
[3])];
231 ctx
->keys
[i
+1] = cast_sbox5
[U8b(t
[0])] ^ cast_sbox6
[U8a(t
[0])]
232 ^ cast_sbox7
[U8c(t
[3])] ^ cast_sbox8
[U8d(t
[3])];
233 ctx
->keys
[i
+2] = cast_sbox5
[U8d(t
[1])] ^ cast_sbox6
[U8c(t
[1])]
234 ^ cast_sbox7
[U8a(t
[2])] ^ cast_sbox8
[U8b(t
[2])];
235 ctx
->keys
[i
+3] = cast_sbox5
[U8b(t
[1])] ^ cast_sbox6
[U8a(t
[1])]
236 ^ cast_sbox7
[U8c(t
[2])] ^ cast_sbox8
[U8d(t
[2])];
241 ctx
->keys
[i
+0] ^= cast_sbox5
[U8c(z
[0])];
242 ctx
->keys
[i
+1] ^= cast_sbox6
[U8c(z
[1])];
243 ctx
->keys
[i
+2] ^= cast_sbox7
[U8b(z
[2])];
244 ctx
->keys
[i
+3] ^= cast_sbox8
[U8a(z
[3])];
247 ctx
->keys
[i
+0] ^= cast_sbox5
[U8a(x
[2])];
248 ctx
->keys
[i
+1] ^= cast_sbox6
[U8b(x
[3])];
249 ctx
->keys
[i
+2] ^= cast_sbox7
[U8d(x
[0])];
250 ctx
->keys
[i
+3] ^= cast_sbox8
[U8d(x
[1])];
253 ctx
->keys
[i
+0] ^= cast_sbox5
[U8b(z
[2])];
254 ctx
->keys
[i
+1] ^= cast_sbox6
[U8a(z
[3])];
255 ctx
->keys
[i
+2] ^= cast_sbox7
[U8c(z
[0])];
256 ctx
->keys
[i
+3] ^= cast_sbox8
[U8c(z
[1])];
259 ctx
->keys
[i
+0] ^= cast_sbox5
[U8d(x
[0])];
260 ctx
->keys
[i
+1] ^= cast_sbox6
[U8d(x
[1])];
261 ctx
->keys
[i
+2] ^= cast_sbox7
[U8a(x
[2])];
262 ctx
->keys
[i
+3] ^= cast_sbox8
[U8b(x
[3])];
266 ctx
->keys
[i
+0] &= 31;
267 ctx
->keys
[i
+1] &= 31;
268 ctx
->keys
[i
+2] &= 31;
269 ctx
->keys
[i
+3] &= 31;
273 for (i
= 0; i
< 4; i
++) {
274 t
[i
] = x
[i
] = z
[i
] = 0;