3 * $Id: rc5.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
5 * The RC5-32/12 block cipher
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Header files ------------------------------------------------------*/
36 #include <mLib/alloc.h>
37 #include <mLib/bits.h>
44 /*----- Global variables --------------------------------------------------*/
46 const octet rc5_keysz[] = { KSZ_RANGE, RC5_KEYSZ, 1, 255, 1 };
48 /*----- Internal magical constants ----------------------------------------*/
50 #define T ((RC5_ROUNDS + 1) * 2)
54 /*----- Main code ---------------------------------------------------------*/
56 /* --- @rc5_init@ --- *
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
64 * Use: Initializes an RC5 key block.
67 void rc5_init(rc5_ctx *k, const void *sbuf, size_t sz)
72 /* --- Set up the @L@ table --- *
74 * This is slightly unfortunately defined.
81 const octet *p = sbuf;
83 /* --- Create the buffer --- */
86 l = XS_ALLOC(w * sizeof(uint32));
88 /* --- Extract the key material --- */
90 for (i = 0; sz > 3; i++) {
96 /* --- Fix up the tail end --- */
100 if (sz > 1) x |= (U8(*p++) << 8);
101 if (sz > 2) x |= (U8(*p++) << 16);
106 /* --- Initialize the @S@ table --- */
112 for (i = 1; i < T; i++)
113 k->s[i] = k->s[i - 1] + Q;
116 /* --- Mix in the key --- */
119 int m = 3 * (w > T ? w : T);
123 for (c = i = j = a = b = 0; c < m; c++) {
127 k->s[i] = a = ROL32(x, 3);
128 i++; if (i >= T) i = 0;
131 l[j] = b = ROL32(x, a + b);
132 j++; if (j >= w) j = 0;
136 memset(l, 0, w * sizeof(uint32));
140 /* --- @EROUND@, @DROUND@ --- */
142 #define EROUND(x, y, k) do { \
144 _x = x ^ y; x = ROL32(_x, y) + k[0]; \
145 _x = y ^ x; y = ROL32(_x, x) + k[1]; \
149 #define DROUND(x, y, k) do { \
152 _x = y - k[1]; y = ROR32(_x, x) ^ x; \
153 _x = x - k[0]; x = ROR32(_x, y) ^ y; \
156 /* --- @EBLK@, @DBLK@ --- */
158 #define EBLK(a, b, c, d, k) do { \
160 const uint32 *_k = (k)->s; \
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); \
182 #define DBLK(a, b, c, d, k) do { \
184 const uint32 *_k = (k)->s + T; \
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); \
207 /* --- @rc5_eblk@, @rc5_dblk@ --- *
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
215 * Use: Low level block encryption and decryption.
218 void rc5_eblk(const rc5_ctx *k, const uint32 *s, uint32 *d)
220 EBLK(s[0], s[1], d[0], d[1], k);
223 void rc5_dblk(const rc5_ctx *k, const uint32 *s, uint32 *d)
225 DBLK(s[0], s[1], d[0], d[1], k);
228 /* --- Test rig --- */
232 /*----- That's all, folks -------------------------------------------------*/