chiark / gitweb /
cleanup: Big pile of whitespace fixes, all at once.
[catacomb] / rc5.c
1 /* -*-c-*-
2  *
3  * $Id: rc5.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
4  *
5  * The RC5-32/12 block cipher
6  *
7  * (c) 1999 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 /*----- 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
39 #include "arena.h"
40 #include "blkc.h"
41 #include "gcipher.h"
42 #include "rc5.h"
43
44 /*----- Global variables --------------------------------------------------*/
45
46 const octet rc5_keysz[] = { KSZ_RANGE, RC5_KEYSZ, 1, 255, 1 };
47
48 /*----- Internal magical constants ----------------------------------------*/
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
67 void 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
77   KSZ_ASSERT(rc5, sz);
78
79   {
80     int i;
81     const octet *p = sbuf;
82
83     /* --- Create the buffer --- */
84
85     w = (sz + 3) / 4;
86     l = XS_ALLOC(w * sizeof(uint32));
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
136   memset(l, 0, w * sizeof(uint32));
137   XS_FREE(l);
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
218 void 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
223 void 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
230 BLKC_TEST(RC5, rc5)
231
232 /*----- That's all, folks -------------------------------------------------*/