4 * Copyright (c) 1999 Pekka Riikonen <priikone@poseidon.pspt.fi>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish, dis-
10 * tribute, sublicense, and/or sell copies of the Software, and to permit
11 * persons to whom the Software is furnished to do so, subject to the fol-
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
19 * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
20 * SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
21 * ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * Except as contained in this notice, the name of the authors shall
26 * not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
33 * Based on RC5 reference code and on description of Bruce Schneier's
34 * Applied Cryptography.
36 * This implementation has a word size of 32 bits, a rounds of 16 and
37 * variable key length from 128 and 192 up to 256 bits.
41 #include "silcincludes.h"
45 * SILC Crypto API for RC5
48 /* Sets the key for the cipher. */
50 SILC_CIPHER_API_SET_KEY(rc5)
54 SILC_GET_WORD_KEY(key, k, keylen);
55 rc5_set_key((RC5Context *)context, k, keylen);
60 /* Sets the string as a new key for the cipher. The string is first
61 hashed and then used as a new key. */
63 SILC_CIPHER_API_SET_KEY_WITH_STRING(rc5)
65 /* unsigned char key[md5_hash_len];
66 SilcMarsContext *ctx = (SilcMarsContext *)context;
68 make_md5_hash(string, &key);
69 memcpy(&ctx->key, mars_set_key(&key, keylen), keylen);
70 memset(&key, 'F', sizeoof(key));
76 /* Returns the size of the cipher context. */
78 SILC_CIPHER_API_CONTEXT_LEN(rc5)
80 return sizeof(RC5Context);
83 /* Encrypts with the cipher in CBC mode. Source and destination buffers
84 maybe one and same. */
86 SILC_CIPHER_API_ENCRYPT_CBC(rc5)
91 SILC_CBC_GET_IV(tiv, iv);
93 SILC_CBC_ENC_PRE(tiv, src);
94 rc5_encrypt((RC5Context *)context, tiv, tiv);
95 SILC_CBC_ENC_POST(tiv, dst, src);
97 for (i = 16; i < len; i += 16) {
98 SILC_CBC_ENC_PRE(tiv, src);
99 rc5_encrypt((RC5Context *)context, tiv, tiv);
100 SILC_CBC_ENC_POST(tiv, dst, src);
103 SILC_CBC_PUT_IV(tiv, iv);
108 /* Decrypts with the cipher in CBC mode. Source and destination buffers
109 maybe one and same. */
111 SILC_CIPHER_API_DECRYPT_CBC(rc5)
113 uint32 tmp[4], tmp2[4], tiv[4];
116 SILC_CBC_GET_IV(tiv, iv);
118 SILC_CBC_DEC_PRE(tmp, src);
119 rc5_decrypt((RC5Context *)context, tmp, tmp2);
120 SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
122 for (i = 16; i < len; i += 16) {
123 SILC_CBC_DEC_PRE(tmp, src);
124 rc5_decrypt((RC5Context *)context, tmp, tmp2);
125 SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
128 SILC_CBC_PUT_IV(tiv, iv);
134 #define RC5E(i, A, B) \
136 A = rotl(A, B) + S[i]; \
138 B = rotl(B, A) + S[i + 1];
141 #define RC5D(i, A, B) \
143 B = rotr(B, A) ^ A; \
149 int rc5_set_key(RC5Context *ctx, const uint32 in_key[], int key_len)
151 u32 i, j, k, A, B, L[c];
152 u32 *out_key = ctx->out_key;
154 if (key_len < b || key_len > (2 * b))
158 for (i = 0; i < key_len / w; i++)
161 /* init key array (S) */
162 out_key[0] = 0xb7e15163;
163 for (i = 1; i < t; i++)
164 out_key[i] = out_key[i - 1] + 0x9e3779b9;
166 /* mix L and key array (S) */
168 for (k = i = j = 0; k < (3 * t); k++) {
169 A = rotl(out_key[i] + (A + B), 3);
171 B = rotl(L[j] + B, B);
181 /* Encrypts *one* block at a time. */
183 int rc5_encrypt(RC5Context *ctx, u32 *in, u32 *out)
186 u32 *S = ctx->out_key;
191 RC5E(2, A, B); RC5E(4, A, B);
192 RC5E(6, A, B); RC5E(8, A, B);
193 RC5E(10, A, B); RC5E(12, A, B);
194 RC5E(14, A, B); RC5E(16, A, B);
195 RC5E(18, A, B); RC5E(20, A, B);
196 RC5E(22, A, B); RC5E(24, A, B);
197 RC5E(26, A, B); RC5E(28, A, B);
198 RC5E(30, A, B); RC5E(32, A, B);
206 /* Decrypts *one* block at a time. */
208 int rc5_decrypt(RC5Context *ctx, u32 *in, u32 *out)
211 u32 *S = ctx->out_key;
216 RC5D(32, A, B); RC5D(30, A, B);
217 RC5D(28, A, B); RC5D(26, A, B);
218 RC5D(24, A, B); RC5D(22, A, B);
219 RC5D(20, A, B); RC5D(18, A, B);
220 RC5D(16, A, B); RC5D(14, A, B);
221 RC5D(12, A, B); RC5D(10, A, B);
222 RC5D(8, A, B); RC5D(6, A, B);
223 RC5D(4, A, B); RC5D(2, A, B);