Add an internal-representation no-op function.
[u/mdw/catacomb] / blowfish.c
CommitLineData
d03ab969 1/* -*-c-*-
2 *
2e6a5ab5 3 * $Id: blowfish.c,v 1.2 2000/06/17 10:47:56 mdw Exp $
d03ab969 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 $
2e6a5ab5 33 * Revision 1.2 2000/06/17 10:47:56 mdw
34 * Tidy round function a little. Support new key size interface.
35 *
d03ab969 36 * Revision 1.1 1999/09/03 08:41:11 mdw
37 * Initial import.
38 *
39 */
40
41/*----- Header files ------------------------------------------------------*/
42
43#include <mLib/bits.h>
44
45#include "blowfish.h"
2e6a5ab5 46#include "blowfish-tab.h"
d03ab969 47#include "blkc.h"
2e6a5ab5 48#include "gcipher.h"
d03ab969 49#include "paranoia.h"
50
51/*----- Global variables --------------------------------------------------*/
52
53static blowfish_ctx ikey = BLOWFISH_IKEY;
54
2e6a5ab5 55const octet blowfish_keysz[] = { KSZ_RANGE, BLOWFISH_KEYSZ, 1, 56, 1 };
56
d03ab969 57/*----- Macros ------------------------------------------------------------*/
58
2e6a5ab5 59#define ROUND(k, x, y, r) do { \
60 x ^= *r; \
61 y ^= ((k->s0[U8(x >> 24)] + \
62 k->s1[U8(x >> 16)]) ^ \
63 k->s2[U8(x >> 8)]) + \
64 k->s3[U8(x >> 0)]; \
65} while (0)
d03ab969 66
67#define EBLK(k, a, b, c, d) do { \
2e6a5ab5 68 const uint32 *_r = k->p; \
69 uint32 _x = a; \
70 uint32 _y = b; \
71 ROUND(k, _x, _y, _r++); \
72 ROUND(k, _y, _x, _r++); \
73 ROUND(k, _x, _y, _r++); \
74 ROUND(k, _y, _x, _r++); \
75 ROUND(k, _x, _y, _r++); \
76 ROUND(k, _y, _x, _r++); \
77 ROUND(k, _x, _y, _r++); \
78 ROUND(k, _y, _x, _r++); \
79 ROUND(k, _x, _y, _r++); \
80 ROUND(k, _y, _x, _r++); \
81 ROUND(k, _x, _y, _r++); \
82 ROUND(k, _y, _x, _r++); \
83 ROUND(k, _x, _y, _r++); \
84 ROUND(k, _y, _x, _r++); \
85 ROUND(k, _x, _y, _r++); \
86 ROUND(k, _y, _x, _r++); \
87 c = _y ^ k->p[17]; \
88 d = _x ^ k->p[16]; \
d03ab969 89} while (0)
90
91#define DBLK(k, a, b, c, d) do { \
2e6a5ab5 92 const uint32 *_r = k->p + 18; \
93 uint32 _x = a; \
94 uint32 _y = b; \
95 ROUND(k, _x, _y, --_r); \
96 ROUND(k, _y, _x, --_r); \
97 ROUND(k, _x, _y, --_r); \
98 ROUND(k, _y, _x, --_r); \
99 ROUND(k, _x, _y, --_r); \
100 ROUND(k, _y, _x, --_r); \
101 ROUND(k, _x, _y, --_r); \
102 ROUND(k, _y, _x, --_r); \
103 ROUND(k, _x, _y, --_r); \
104 ROUND(k, _y, _x, --_r); \
105 ROUND(k, _x, _y, --_r); \
106 ROUND(k, _y, _x, --_r); \
107 ROUND(k, _x, _y, --_r); \
108 ROUND(k, _y, _x, --_r); \
109 ROUND(k, _x, _y, --_r); \
110 ROUND(k, _y, _x, --_r); \
111 c = _y ^ k->p[0]; \
112 d = _x ^ k->p[1]; \
d03ab969 113} while (0)
114
115/*----- Low-level encryption interface ------------------------------------*/
116
117/* --- @blowfish_init@ --- *
118 *
119 * Arguments: @blowfish_ctx *k@ = pointer to key block to fill in
120 * @const void *buf@ = pointer to buffer of key material
121 * @size_t sz@ = size of key material
122 *
123 * Returns: ---
124 *
125 * Use: Initializes a Blowfish key buffer. Blowfish accepts
126 * a more-or-less arbitrary size key.
127 */
128
129void blowfish_init(blowfish_ctx *k, const void *buf, size_t sz)
130{
2e6a5ab5 131 KSZ_ASSERT(blowfish, sz);
132
d03ab969 133 /* --- Copy the initial value over --- */
134
135 memcpy(k, &ikey, sizeof(ikey));
136
137 /* --- Initialize the %$P$% array --- */
138
139 {
140 const octet *p = buf;
141 const octet *q = p + sz;
142 int i = 0, j = 0;
143 uint32 x = 0;
144
145 while (i < 18) {
146 x = (x << 8) | U8(*p++);
147 if (p >= q)
148 p = buf;
149 if (++j >= 4) {
150 k->p[i++] ^= x;
151 x = 0;
152 j = 0;
153 }
154 }
155
156 x = 0;
157 }
158
159 /* --- Now mangle the complete array of keys --- */
160
161 {
162 uint32 b[2];
163 int i;
164
165 b[0] = b[1] = 0;
166
167 for (i = 0; i < 18; i += 2) {
168 blowfish_eblk(k, b, b);
169 k->p[i] = b[0]; k->p[i + 1] = b[1];
170 }
171
172 for (i = 0; i < 256; i += 2) {
173 blowfish_eblk(k, b, b);
174 k->s0[i] = b[0]; k->s0[i + 1] = b[1];
175 }
176
177 for (i = 0; i < 256; i += 2) {
178 blowfish_eblk(k, b, b);
179 k->s1[i] = b[0]; k->s1[i + 1] = b[1];
180 }
181
182 for (i = 0; i < 256; i += 2) {
183 blowfish_eblk(k, b, b);
184 k->s2[i] = b[0]; k->s2[i + 1] = b[1];
185 }
186
187 for (i = 0; i < 256; i += 2) {
188 blowfish_eblk(k, b, b);
189 k->s3[i] = b[0]; k->s3[i + 1] = b[1];
190 }
191
192 BURN(b);
193 }
194}
195
196/* --- @blowfish_eblk@, @blowfish_dblk@ --- *
197 *
198 * Arguments: @const blowfish_ctx *k@ = pointer to key block
199 * @const uint32 s[2]@ = pointer to source block
200 * @uint32 d[2]@ = pointer to destination block
201 *
202 * Returns: ---
203 *
204 * Use: Low-level block encryption and decryption.
205 */
206
207void blowfish_eblk(const blowfish_ctx *k, const uint32 *s, uint32 *d)
208{
209 EBLK(k, s[0], s[1], d[0], d[1]);
210}
211
212void blowfish_dblk(const blowfish_ctx *k, const uint32 *s, uint32 *d)
213{
214 DBLK(k, s[0], s[1], d[0], d[1]);
215}
216
217BLKC_TEST(BLOWFISH, blowfish)
218
219/*----- That's all, folks -------------------------------------------------*/