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