Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nettle / cast128.c
blob512c55d2cc71a6e3ecd312883e822b93d247870c
1 /* cast128.c
3 * The CAST-128 block cipher, described in RFC 2144.
4 */
6 /* CAST-128 in C
7 * Written by Steve Reid <sreid@sea-to-sky.net>
8 * 100% Public Domain - no warranty
9 * Released 1997.10.11
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,
29 * MA 02111-1301, USA.
32 #if HAVE_CONFIG_H
33 # include "config.h"
34 #endif
36 #include <assert.h>
38 #include "cast128.h"
39 #include "cast128_sboxes.h"
41 #include "macros.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)]; \
58 } while (0)
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)]; \
63 } while (0)
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)]; \
68 } while (0)
71 /***** Encryption Function *****/
73 void
74 cast128_encrypt(const struct cast128_ctx *ctx,
75 unsigned length, uint8_t *dst,
76 const uint8_t *src)
78 FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE)
80 uint32_t t, l, r;
82 /* Get inblock into l,r */
83 l = READ_UINT32(src);
84 r = READ_UINT32(src+4);
86 /* Do the work */
87 F1(l, r, 0);
88 F2(r, l, 1);
89 F3(l, r, 2);
90 F1(r, l, 3);
91 F2(l, r, 4);
92 F3(r, l, 5);
93 F1(l, r, 6);
94 F2(r, l, 7);
95 F3(l, r, 8);
96 F1(r, l, 9);
97 F2(l, r, 10);
98 F3(r, l, 11);
99 /* Only do full 16 rounds if key length > 80 bits */
100 if (ctx->rounds > 12) {
101 F1(l, r, 12);
102 F2(r, l, 13);
103 F3(l, r, 14);
104 F1(r, l, 15);
106 /* Put l,r into outblock */
107 WRITE_UINT32(dst, r);
108 WRITE_UINT32(dst + 4, l);
109 /* Wipe clean */
110 t = l = r = 0;
115 /***** Decryption Function *****/
117 void
118 cast128_decrypt(const struct cast128_ctx *ctx,
119 unsigned length, uint8_t *dst,
120 const uint8_t *src)
122 FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE)
124 uint32_t t, l, r;
126 /* Get inblock into l,r */
127 r = READ_UINT32(src);
128 l = READ_UINT32(src+4);
130 /* Do the work */
131 /* Only do full 16 rounds if key length > 80 bits */
132 if (ctx->rounds > 12) {
133 F1(r, l, 15);
134 F3(l, r, 14);
135 F2(r, l, 13);
136 F1(l, r, 12);
138 F3(r, l, 11);
139 F2(l, r, 10);
140 F1(r, l, 9);
141 F3(l, r, 8);
142 F2(r, l, 7);
143 F1(l, r, 6);
144 F3(r, l, 5);
145 F2(l, r, 4);
146 F1(r, l, 3);
147 F3(l, r, 2);
148 F2(r, l, 1);
149 F1(l, r, 0);
151 /* Put l,r into outblock */
152 WRITE_UINT32(dst, l);
153 WRITE_UINT32(dst + 4, r);
155 /* Wipe clean */
156 t = l = r = 0;
160 /***** Key Schedule *****/
162 void
163 cast128_set_key(struct cast128_ctx *ctx,
164 unsigned keybytes, const uint8_t *rawkey)
166 uint32_t t[4], z[4], x[4];
167 unsigned i;
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++) {
175 x[i] = 0;
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) {
185 switch (i & 4) {
186 case 0:
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])];
199 break;
200 case 4:
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])];
213 break;
215 switch (i & 12) {
216 case 0:
217 case 12:
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])];
226 break;
227 case 4:
228 case 8:
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])];
237 break;
239 switch (i & 12) {
240 case 0:
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])];
245 break;
246 case 4:
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])];
251 break;
252 case 8:
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])];
257 break;
258 case 12:
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])];
263 break;
265 if (i >= 16) {
266 ctx->keys[i+0] &= 31;
267 ctx->keys[i+1] &= 31;
268 ctx->keys[i+2] &= 31;
269 ctx->keys[i+3] &= 31;
272 /* Wipe clean */
273 for (i = 0; i < 4; i++) {
274 t[i] = x[i] = z[i] = 0;