chiark / gitweb /
Miscellaneous constification.
[catacomb] / blowfish.c
1 /* -*-c-*-
2  *
3  * $Id: blowfish.c,v 1.3 2004/04/02 01:03:49 mdw Exp $
4  *
5  * The Blowfish block cipher
6  *
7  * (c) 1998 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: blowfish.c,v $
33  * Revision 1.3  2004/04/02 01:03:49  mdw
34  * Miscellaneous constification.
35  *
36  * Revision 1.2  2000/06/17 10:47:56  mdw
37  * Tidy round function a little.  Support new key size interface.
38  *
39  * Revision 1.1  1999/09/03 08:41:11  mdw
40  * Initial import.
41  *
42  */
43
44 /*----- Header files ------------------------------------------------------*/
45
46 #include <mLib/bits.h>
47
48 #include "blowfish.h"
49 #include "blowfish-tab.h"
50 #include "blkc.h"
51 #include "gcipher.h"
52 #include "paranoia.h"
53
54 /*----- Global variables --------------------------------------------------*/
55
56 static const blowfish_ctx ikey = BLOWFISH_IKEY;
57
58 const octet blowfish_keysz[] = { KSZ_RANGE, BLOWFISH_KEYSZ, 1, 56, 1 };
59
60 /*----- Macros ------------------------------------------------------------*/
61
62 #define ROUND(k, x, y, r) do {                                          \
63   x ^= *r;                                                              \
64   y ^= ((k->s0[U8(x >> 24)] +                                           \
65          k->s1[U8(x >> 16)]) ^                                          \
66          k->s2[U8(x >>  8)]) +                                          \
67          k->s3[U8(x >>  0)];                                            \
68 } while (0)
69
70 #define EBLK(k, a, b, c, d) do {                                        \
71   const uint32 *_r = k->p;                                              \
72   uint32 _x = a;                                                        \
73   uint32 _y = b;                                                        \
74   ROUND(k, _x, _y, _r++);                                               \
75   ROUND(k, _y, _x, _r++);                                               \
76   ROUND(k, _x, _y, _r++);                                               \
77   ROUND(k, _y, _x, _r++);                                               \
78   ROUND(k, _x, _y, _r++);                                               \
79   ROUND(k, _y, _x, _r++);                                               \
80   ROUND(k, _x, _y, _r++);                                               \
81   ROUND(k, _y, _x, _r++);                                               \
82   ROUND(k, _x, _y, _r++);                                               \
83   ROUND(k, _y, _x, _r++);                                               \
84   ROUND(k, _x, _y, _r++);                                               \
85   ROUND(k, _y, _x, _r++);                                               \
86   ROUND(k, _x, _y, _r++);                                               \
87   ROUND(k, _y, _x, _r++);                                               \
88   ROUND(k, _x, _y, _r++);                                               \
89   ROUND(k, _y, _x, _r++);                                               \
90   c = _y ^ k->p[17];                                                    \
91   d = _x ^ k->p[16];                                                    \
92 } while (0)
93
94 #define DBLK(k, a, b, c, d) do {                                        \
95   const uint32 *_r = k->p + 18;                                         \
96   uint32 _x = a;                                                        \
97   uint32 _y = b;                                                        \
98   ROUND(k, _x, _y, --_r);                                               \
99   ROUND(k, _y, _x, --_r);                                               \
100   ROUND(k, _x, _y, --_r);                                               \
101   ROUND(k, _y, _x, --_r);                                               \
102   ROUND(k, _x, _y, --_r);                                               \
103   ROUND(k, _y, _x, --_r);                                               \
104   ROUND(k, _x, _y, --_r);                                               \
105   ROUND(k, _y, _x, --_r);                                               \
106   ROUND(k, _x, _y, --_r);                                               \
107   ROUND(k, _y, _x, --_r);                                               \
108   ROUND(k, _x, _y, --_r);                                               \
109   ROUND(k, _y, _x, --_r);                                               \
110   ROUND(k, _x, _y, --_r);                                               \
111   ROUND(k, _y, _x, --_r);                                               \
112   ROUND(k, _x, _y, --_r);                                               \
113   ROUND(k, _y, _x, --_r);                                               \
114   c = _y ^ k->p[0];                                                     \
115   d = _x ^ k->p[1];                                                     \
116 } while (0)
117
118 /*----- Low-level encryption interface ------------------------------------*/
119
120 /* --- @blowfish_init@ --- *
121  *
122  * Arguments:   @blowfish_ctx *k@ = pointer to key block to fill in
123  *              @const void *buf@ = pointer to buffer of key material
124  *              @size_t sz@ = size of key material
125  *
126  * Returns:     ---
127  *
128  * Use:         Initializes a Blowfish key buffer.  Blowfish accepts
129  *              a more-or-less arbitrary size key.
130  */
131
132 void blowfish_init(blowfish_ctx *k, const void *buf, size_t sz)
133 {
134   KSZ_ASSERT(blowfish, sz);
135
136   /* --- Copy the initial value over --- */
137
138   memcpy(k, &ikey, sizeof(ikey));
139
140   /* --- Initialize the %$P$% array --- */
141
142   {
143     const octet *p = buf;
144     const octet *q = p + sz;
145     int i = 0, j = 0;
146     uint32 x = 0;
147
148     while (i < 18) {
149       x = (x << 8) | U8(*p++);
150       if (p >= q)
151         p = buf;
152       if (++j >= 4) {
153         k->p[i++] ^= x;
154         x = 0;
155         j = 0;
156       }
157     }
158
159     x = 0;
160   }
161
162   /* --- Now mangle the complete array of keys --- */
163
164   {
165     uint32 b[2];
166     int i;
167
168     b[0] = b[1] = 0;
169
170     for (i = 0; i < 18; i += 2) {
171       blowfish_eblk(k, b, b);
172       k->p[i] = b[0]; k->p[i + 1] = b[1];
173     }
174
175     for (i = 0; i < 256; i += 2) {
176       blowfish_eblk(k, b, b);
177       k->s0[i] = b[0]; k->s0[i + 1] = b[1];
178     }
179
180     for (i = 0; i < 256; i += 2) {
181       blowfish_eblk(k, b, b);
182       k->s1[i] = b[0]; k->s1[i + 1] = b[1];
183     }
184
185     for (i = 0; i < 256; i += 2) {
186       blowfish_eblk(k, b, b);
187       k->s2[i] = b[0]; k->s2[i + 1] = b[1];
188     }
189
190     for (i = 0; i < 256; i += 2) {
191       blowfish_eblk(k, b, b);
192       k->s3[i] = b[0]; k->s3[i + 1] = b[1];
193     }
194
195     BURN(b);
196   }
197 }
198
199 /* --- @blowfish_eblk@, @blowfish_dblk@ --- *
200  *
201  * Arguments:   @const blowfish_ctx *k@ = pointer to key block
202  *              @const uint32 s[2]@ = pointer to source block
203  *              @uint32 d[2]@ = pointer to destination block
204  *
205  * Returns:     ---
206  *
207  * Use:         Low-level block encryption and decryption.
208  */
209
210 void blowfish_eblk(const blowfish_ctx *k, const uint32 *s, uint32 *d)
211 {
212   EBLK(k, s[0], s[1], d[0], d[1]);
213 }
214
215 void blowfish_dblk(const blowfish_ctx *k, const uint32 *s, uint32 *d)
216 {
217   DBLK(k, s[0], s[1], d[0], d[1]);
218 }
219
220 BLKC_TEST(BLOWFISH, blowfish)
221
222 /*----- That's all, folks -------------------------------------------------*/