3 * $Id: rc5.c,v 1.2 2000/06/17 11:56:00 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 /*----- Revision history --------------------------------------------------*
33 * Revision 1.2 2000/06/17 11:56:00 mdw
34 * New key size interface. Use secure arena for memory allocation.
36 * Revision 1.1 1999/09/03 08:41:12 mdw
41 /*----- Header files ------------------------------------------------------*/
47 #include <mLib/alloc.h>
48 #include <mLib/bits.h>
55 /*----- Global variables --------------------------------------------------*/
57 const octet rc5_keysz
[] = { KSZ_RANGE
, RC5_KEYSZ
, 1, 255, 1 };
59 /*----- Internal magical constants ----------------------------------------*/
61 #define T ((RC5_ROUNDS + 1) * 2)
65 /*----- Main code ---------------------------------------------------------*/
67 /* --- @rc5_init@ --- *
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
75 * Use: Initializes an RC5 key block.
78 void rc5_init(rc5_ctx
*k
, const void *sbuf
, size_t sz
)
83 /* --- Set up the @L@ table --- *
85 * This is slightly unfortunately defined.
92 const octet
*p
= sbuf
;
94 /* --- Create the buffer --- */
97 l
= XS_ALLOC(w
* sizeof(uint32
));
99 /* --- Extract the key material --- */
101 for (i
= 0; sz
> 3; i
++) {
107 /* --- Fix up the tail end --- */
111 if (sz
> 1) x
|= (U8(*p
++) << 8);
112 if (sz
> 2) x
|= (U8(*p
++) << 16);
117 /* --- Initialize the @S@ table --- */
123 for (i
= 1; i
< T
; i
++)
124 k
->s
[i
] = k
->s
[i
- 1] + Q
;
127 /* --- Mix in the key --- */
130 int m
= 3 * (w
> T ? w
: T
);
134 for (c
= i
= j
= a
= b
= 0; c
< m
; c
++) {
138 k
->s
[i
] = a
= ROL32(x
, 3);
139 i
++; if (i
>= T
) i
= 0;
142 l
[j
] = b
= ROL32(x
, a
+ b
);
143 j
++; if (j
>= w
) j
= 0;
147 memset(l
, 0, w
* sizeof(uint32
));
151 /* --- @EROUND@, @DROUND@ --- */
153 #define EROUND(x, y, k) do { \
155 _x = x ^ y; x = ROL32(_x, y) + k[0]; \
156 _x = y ^ x; y = ROL32(_x, x) + k[1]; \
160 #define DROUND(x, y, k) do { \
163 _x = y - k[1]; y = ROR32(_x, x) ^ x; \
164 _x = x - k[0]; x = ROR32(_x, y) ^ y; \
167 /* --- @EBLK@, @DBLK@ --- */
169 #define EBLK(a, b, c, d, k) do { \
171 const uint32 *_k = (k)->s; \
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); \
193 #define DBLK(a, b, c, d, k) do { \
195 const uint32 *_k = (k)->s + T; \
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); \
218 /* --- @rc5_eblk@, @rc5_dblk@ --- *
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
226 * Use: Low level block encryption and decryption.
229 void rc5_eblk(const rc5_ctx
*k
, const uint32
*s
, uint32
*d
)
231 EBLK(s
[0], s
[1], d
[0], d
[1], k
);
234 void rc5_dblk(const rc5_ctx
*k
, const uint32
*s
, uint32
*d
)
236 DBLK(s
[0], s
[1], d
[0], d
[1], k
);
239 /* --- Test rig --- */
243 /*----- That's all, folks -------------------------------------------------*/