[Title] Add packaging/nettle.spec to build nettle on OBS system
[external/nettle.git] / cast128.c
1 /* cast128.c
2  *
3  * The CAST-128 block cipher, described in RFC 2144.
4  */
5
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
10  */
11
12 /* nettle, low-level cryptographics library
13  *
14  * Copyright (C) 2001 Niels Möller
15  *  
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.
20  * 
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.
25  * 
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., 59 Temple Place - Suite 330, Boston,
29  * MA 02111-1307, USA.
30  */
31
32 #if HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <assert.h>
37
38 #include "cast128.h"
39 #include "cast128_sboxes.h"
40
41 #include "macros.h"
42
43 #define CAST_SMALL_KEY 10
44 #define CAST_SMALL_ROUNDS 12
45 #define CAST_FULL_ROUNDS 16
46
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) )
52
53 /* Circular left shift */
54 #define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
55
56 /* CAST-128 uses three different round functions */
57 #define F1(l, r, i) \
58         t = ROL(ctx->keys[i] + r, ctx->keys[i+16]); \
59         l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \
60          - cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
61 #define F2(l, r, i) \
62         t = ROL(ctx->keys[i] ^ r, ctx->keys[i+16]); \
63         l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \
64          + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
65 #define F3(l, r, i) \
66         t = ROL(ctx->keys[i] - r, ctx->keys[i+16]); \
67         l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \
68          ^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
69
70
71 /***** Encryption Function *****/
72
73 void
74 cast128_encrypt(const struct cast128_ctx *ctx,
75                 unsigned length, uint8_t *dst,
76                 const uint8_t *src)
77 {
78   FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE)
79     {
80       uint32_t t, l, r;
81
82       /* Get inblock into l,r */
83       l = READ_UINT32(src);
84       r = READ_UINT32(src+4);
85
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);
105       }
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;
111     }
112 }
113
114
115 /***** Decryption Function *****/
116
117 void
118 cast128_decrypt(const struct cast128_ctx *ctx,
119                 unsigned length, uint8_t *dst,
120                 const uint8_t *src)
121 {
122   FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE)
123     {
124       uint32_t t, l, r;
125
126       /* Get inblock into l,r */
127       r = READ_UINT32(src);
128       l = READ_UINT32(src+4);
129
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);
137       }
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);
150
151       /* Put l,r into outblock */
152       WRITE_UINT32(dst, l);
153       WRITE_UINT32(dst + 4, r);
154
155       /* Wipe clean */
156       t = l = r = 0;
157     }
158 }
159
160 /***** Key Schedule *****/
161
162 void
163 cast128_set_key(struct cast128_ctx *ctx,
164                 unsigned keybytes, const uint8_t *rawkey)
165 {
166   uint32_t t[4], z[4], x[4];
167   unsigned i;
168
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;
172
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];
180   }
181   /* FIXME: For the shorter key sizes, the last 4 subkeys are not
182      used, and need not be generatedd, 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;
214     }
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;
238     }
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;
264     }
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;
270     }
271   }
272   /* Wipe clean */
273   for (i = 0; i < 4; i++) {
274     t[i] = x[i] = z[i] = 0;
275   }
276 }