cleanup: Big pile of whitespace fixes, all at once.
[u/mdw/catacomb] / rc5.c
CommitLineData
d03ab969 1/* -*-c-*-
2 *
b817bfc6 3 * $Id: rc5.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
d03ab969 4 *
5 * The RC5-32/12 block cipher
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
45c0fd36 10/*----- Licensing notice --------------------------------------------------*
d03ab969 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.
45c0fd36 18 *
d03ab969 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.
45c0fd36 23 *
d03ab969 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
d03ab969 30/*----- Header files ------------------------------------------------------*/
31
32#include <assert.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include <mLib/alloc.h>
37#include <mLib/bits.h>
38
6134d968 39#include "arena.h"
d03ab969 40#include "blkc.h"
6134d968 41#include "gcipher.h"
d03ab969 42#include "rc5.h"
43
6134d968 44/*----- Global variables --------------------------------------------------*/
d03ab969 45
6134d968 46const octet rc5_keysz[] = { KSZ_RANGE, RC5_KEYSZ, 1, 255, 1 };
47
48/*----- Internal magical constants ----------------------------------------*/
d03ab969 49
50#define T ((RC5_ROUNDS + 1) * 2)
51#define P 0xb7e15163
52#define Q 0x9e3779b9
53
54/*----- Main code ---------------------------------------------------------*/
55
56/* --- @rc5_init@ --- *
57 *
58 * Arguments: @rc5_ctx *k@ = pointer to a key block
59 * @const void *sbuf@ = pointer to key material
60 * @size_t sz@ = size of the key material
61 *
62 * Returns: ---
63 *
64 * Use: Initializes an RC5 key block.
65 */
66
67void rc5_init(rc5_ctx *k, const void *sbuf, size_t sz)
68{
69 uint32 *l;
70 size_t w;
71
72 /* --- Set up the @L@ table --- *
73 *
74 * This is slightly unfortunately defined.
75 */
76
6134d968 77 KSZ_ASSERT(rc5, sz);
d03ab969 78
79 {
80 int i;
81 const octet *p = sbuf;
82
83 /* --- Create the buffer --- */
84
85 w = (sz + 3) / 4;
6134d968 86 l = XS_ALLOC(w * sizeof(uint32));
d03ab969 87
88 /* --- Extract the key material --- */
89
90 for (i = 0; sz > 3; i++) {
91 l[i] = LOAD32_L(p);
92 p += 4;
93 sz -= 4;
94 }
95
96 /* --- Fix up the tail end --- */
97
98 if (sz) {
99 uint32 x = U8(*p++);
100 if (sz > 1) x |= (U8(*p++) << 8);
101 if (sz > 2) x |= (U8(*p++) << 16);
102 l[i] = x;
103 }
104 }
105
106 /* --- Initialize the @S@ table --- */
107
108 {
109 int i;
110
111 k->s[0] = P;
112 for (i = 1; i < T; i++)
113 k->s[i] = k->s[i - 1] + Q;
114 }
115
116 /* --- Mix in the key --- */
117
118 {
119 int m = 3 * (w > T ? w : T);
120 int i, j, c;
121 uint32 a, b;
122
123 for (c = i = j = a = b = 0; c < m; c++) {
124 uint32 x;
125
126 x = k->s[i] + a + b;
127 k->s[i] = a = ROL32(x, 3);
128 i++; if (i >= T) i = 0;
129
130 x = l[j] + a + b;
131 l[j] = b = ROL32(x, a + b);
132 j++; if (j >= w) j = 0;
133 }
134 }
135
6134d968 136 memset(l, 0, w * sizeof(uint32));
137 XS_FREE(l);
d03ab969 138}
139
140/* --- @EROUND@, @DROUND@ --- */
141
142#define EROUND(x, y, k) do { \
143 uint32 _x; \
144 _x = x ^ y; x = ROL32(_x, y) + k[0]; \
145 _x = y ^ x; y = ROL32(_x, x) + k[1]; \
146 k += 2; \
147} while (0)
148
149#define DROUND(x, y, k) do { \
150 uint32 _x; \
151 k -= 2; \
152 _x = y - k[1]; y = ROR32(_x, x) ^ x; \
153 _x = x - k[0]; x = ROR32(_x, y) ^ y; \
154} while (0)
155
156/* --- @EBLK@, @DBLK@ --- */
157
158#define EBLK(a, b, c, d, k) do { \
159 uint32 _l, _r; \
160 const uint32 *_k = (k)->s; \
161 \
162 _l = (a) + _k[0]; \
163 _r = (b) + _k[1]; \
164 _k += 2; \
165 \
166 EROUND(_l, _r, _k); \
167 EROUND(_l, _r, _k); \
168 EROUND(_l, _r, _k); \
169 EROUND(_l, _r, _k); \
170 EROUND(_l, _r, _k); \
171 EROUND(_l, _r, _k); \
172 EROUND(_l, _r, _k); \
173 EROUND(_l, _r, _k); \
174 EROUND(_l, _r, _k); \
175 EROUND(_l, _r, _k); \
176 EROUND(_l, _r, _k); \
177 EROUND(_l, _r, _k); \
178 (c) = _l; \
179 (d) = _r; \
180} while (0)
181
182#define DBLK(a, b, c, d, k) do { \
183 uint32 _l, _r; \
184 const uint32 *_k = (k)->s + T; \
185 \
186 _l = (a); \
187 _r = (b); \
188 \
189 DROUND(_l, _r, _k); \
190 DROUND(_l, _r, _k); \
191 DROUND(_l, _r, _k); \
192 DROUND(_l, _r, _k); \
193 DROUND(_l, _r, _k); \
194 DROUND(_l, _r, _k); \
195 DROUND(_l, _r, _k); \
196 DROUND(_l, _r, _k); \
197 DROUND(_l, _r, _k); \
198 DROUND(_l, _r, _k); \
199 DROUND(_l, _r, _k); \
200 DROUND(_l, _r, _k); \
201 \
202 _k -= 2; \
203 (d) = _r - _k[1]; \
204 (c) = _l - _k[0]; \
205} while (0)
206
207/* --- @rc5_eblk@, @rc5_dblk@ --- *
208 *
209 * Arguments: @const rc5_ctx *k@ = pointer to RC5 context block
210 * @const uint32 s[2]@ = pointer to source block
211 * @uint32 *d[2]@ = pointer to destination block
212 *
213 * Returns: ---
214 *
215 * Use: Low level block encryption and decryption.
216 */
217
218void rc5_eblk(const rc5_ctx *k, const uint32 *s, uint32 *d)
219{
220 EBLK(s[0], s[1], d[0], d[1], k);
221}
222
223void rc5_dblk(const rc5_ctx *k, const uint32 *s, uint32 *d)
224{
225 DBLK(s[0], s[1], d[0], d[1], k);
226}
227
228/* --- Test rig --- */
229
230BLKC_TEST(RC5, rc5)
231
232/*----- That's all, folks -------------------------------------------------*/