File Coverage

inc/matrixssl-3-9-3-open/crypto/symmetric/rc2.c
Criterion Covered Total %
statement 66 112 58.9
branch 32 64 50.0
condition n/a
subroutine n/a
pod n/a
total 98 176 55.6


line stmt bran cond sub pod time code
1             /**
2             * @file rc2.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * rc2 cipher implementation.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37             #ifdef USE_MATRIX_RC2
38              
39             /******************************************************************************/
40              
41             static int32_t psRc2InitKey(const unsigned char *key, uint8_t keylen,
42             uint8_t rds, psRc2Key_t *skey);
43             static void psRc2EncryptBlock(const unsigned char *pt, unsigned char *ct,
44             psRc2Key_t *skey);
45             static void psRc2DecryptBlock(const unsigned char *ct, unsigned char *pt,
46             psRc2Key_t *skey);
47              
48             /* 256-entry permutation table, probably derived somehow from pi */
49             static const unsigned char permute[256] = {
50             217, 120, 249, 196, 25, 221, 181, 237, 40, 233, 253, 121, 74, 160, 216, 157,
51             198, 126, 55, 131, 43, 118, 83, 142, 98, 76, 100, 136, 68, 139, 251, 162,
52             23, 154, 89, 245, 135, 179, 79, 19, 97, 69, 109, 141, 9, 129, 125, 50,
53             189, 143, 64, 235, 134, 183, 123, 11, 240, 149, 33, 34, 92, 107, 78, 130,
54             84, 214, 101, 147, 206, 96, 178, 28, 115, 86, 192, 20, 167, 140, 241, 220,
55             18, 117, 202, 31, 59, 190, 228, 209, 66, 61, 212, 48, 163, 60, 182, 38,
56             111, 191, 14, 218, 70, 105, 7, 87, 39, 242, 29, 155, 188, 148, 67, 3,
57             248, 17, 199, 246, 144, 239, 62, 231, 6, 195, 213, 47, 200, 102, 30, 215,
58             8, 232, 234, 222, 128, 82, 238, 247, 132, 170, 114, 172, 53, 77, 106, 42,
59             150, 26, 210, 113, 90, 21, 73, 116, 75, 159, 208, 94, 4, 24, 164, 236,
60             194, 224, 65, 110, 15, 81, 203, 204, 36, 145, 175, 80, 161, 244, 112, 57,
61             153, 124, 58, 133, 35, 184, 180, 122, 252, 2, 54, 91, 37, 85, 151, 49,
62             45, 93, 250, 152, 227, 138, 146, 174, 5, 223, 41, 16, 103, 108, 186, 201,
63             211, 0, 230, 207, 225, 158, 168, 44, 99, 22, 1, 63, 88, 226, 137, 169,
64             13, 56, 52, 27, 171, 51, 255, 176, 187, 72, 12, 95, 185, 177, 205, 46,
65             197, 243, 219, 71, 229, 165, 156, 119, 10, 166, 32, 104, 254, 127, 193, 173
66             };
67              
68             /******************************************************************************/
69              
70 14           int32_t psRc2Init(psRc2Cbc_t *ctx, const unsigned char *IV,
71             const unsigned char *key, uint8_t keylen)
72             {
73             int32 x, err;
74              
75 14 50         if (IV == NULL || key == NULL || ctx == NULL)
    50          
    50          
76             {
77             psTraceCrypto("psRc2Init arg fail\n");
78 0           return PS_ARG_FAIL;
79             }
80             /* setup cipher */
81 14 50         if ((err = psRc2InitKey(key, keylen, 0, &ctx->key)) != PS_SUCCESS)
82             {
83 0           return err;
84             }
85             /* copy IV */
86 126 100         for (x = 0; x < RC2_BLOCKLEN; x++)
87             {
88 112           ctx->IV[x] = IV[x];
89             }
90 14           return PS_SUCCESS;
91             }
92              
93             /******************************************************************************/
94              
95 0           int32_t psRc2Encrypt(psRc2Cbc_t *ctx, const unsigned char *pt,
96             unsigned char *ct, uint32_t len)
97             {
98             int32 x;
99             uint32 i;
100             unsigned char tmp[RC2_BLOCKLEN];
101              
102 0 0         if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0)
    0          
    0          
    0          
103             {
104             psTraceCrypto("Bad parameters to psRc2Encrypt\n");
105 0           return PS_ARG_FAIL;
106             }
107              
108 0 0         for (i = 0; i < len; i += RC2_BLOCKLEN)
109             {
110             /* xor IV against plaintext */
111 0 0         for (x = 0; x < RC2_BLOCKLEN; x++)
112             {
113 0           tmp[x] = pt[x] ^ ctx->IV[x];
114             }
115             /* encrypt */
116 0           psRc2EncryptBlock(tmp, ct, &ctx->key);
117             /* store IV [ciphertext] for a future block */
118 0 0         for (x = 0; x < RC2_BLOCKLEN; x++)
119             {
120 0           ctx->IV[x] = ct[x];
121             }
122 0           ct += RC2_BLOCKLEN;
123 0           pt += RC2_BLOCKLEN;
124             }
125              
126 0           memset(tmp, 0x0, sizeof(tmp));
127 0           return len;
128             }
129              
130             /******************************************************************************/
131              
132 14           int32_t psRc2Decrypt(psRc2Cbc_t *ctx, const unsigned char *ct,
133             unsigned char *pt, uint32_t len)
134             {
135             int32 x;
136             uint32 i;
137             unsigned char tmp[RC2_BLOCKLEN], tmp2[RC2_BLOCKLEN];
138              
139 14 50         if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0)
    50          
    50          
    50          
140             {
141             psTraceCrypto("Bad parameters to psRc2Decrypt\n");
142 0           return PS_ARG_FAIL;
143             }
144 1938 100         for (i = 0; i < len; i += RC2_BLOCKLEN)
145             {
146             /* decrypt the block from ct into tmp */
147 1924           psRc2DecryptBlock(ct, tmp, &ctx->key);
148             /* xor IV against the plaintext of the previous step */
149 17316 100         for (x = 0; x < RC2_BLOCKLEN; x++)
150             {
151             /* copy CT in case ct == pt */
152 15392           tmp2[x] = ct[x];
153             /* actually decrypt the byte */
154 15392           pt[x] = tmp[x] ^ ctx->IV[x];
155             }
156             /* replace IV with this current ciphertext */
157 17316 100         for (x = 0; x < RC2_BLOCKLEN; x++)
158             {
159 15392           ctx->IV[x] = tmp2[x];
160             }
161 1924           ct += RC2_BLOCKLEN;
162 1924           pt += RC2_BLOCKLEN;
163             }
164 14           memset(tmp, 0x0, sizeof(tmp));
165 14           memset(tmp2, 0x0, sizeof(tmp2));
166              
167 14           return len;
168             }
169              
170             /******************************************************************************/
171             /**
172             Initialize the LTC_RC2 block cipher
173             @param key The symmetric key you wish to pass
174             @param keylen The key length in bytes
175             @param num_rounds The number of rounds desired (0 for default)
176             @param skey The key in as scheduled by this function.
177             @return CRYPT_OK if successful
178             */
179 14           static int32_t psRc2InitKey(const unsigned char *key, uint8_t keylen,
180             uint8_t num_rounds, psRc2Key_t *ctx)
181             {
182             unsigned char tmp[128];
183             uint32_t *xkey;
184             uint32_t T8, TM;
185             int32_t i, bits;
186              
187             /* if (keylen < 8 || keylen > 128) { */
188             /* return PS_ARG_FAIL; */
189             /* } */
190              
191 14 50         if (num_rounds != 0 && num_rounds != 16)
    0          
192             {
193 0           return PS_ARG_FAIL;
194             }
195              
196 14           xkey = ctx->xkey;
197 84 100         for (i = 0; i < (int32) keylen; i++)
198             {
199 70           tmp[i] = key[i] & 255;
200             }
201              
202             /* Phase 1: Expand input key to 128 bytes */
203 14 50         if (keylen < 128)
204             {
205 1736 100         for (i = keylen; i < 128; i++)
206             {
207 1722           tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
208             }
209             }
210              
211             /* Phase 2 - reduce effective key size to "bits" */
212 14           bits = keylen << 3;
213 14           T8 = (uint32_t) (bits + 7) >> 3;
214 14           TM = (255 >> (uint32_t) (7 & - bits));
215 14           tmp[128 - T8] = permute[tmp[128 - T8] & TM];
216 1736 100         for (i = 127 - T8; i >= 0; i--)
217             {
218 1722           tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
219             }
220              
221             /* Phase 3 - copy to xkey in little-endian order */
222 910 100         for (i = 0; i < 64; i++)
223             {
224 896           xkey[i] = (uint32_t) tmp[2 * i] + ((uint32_t) tmp[2 * i + 1] << 8);
225             }
226              
227 14           return PS_SUCCESS;
228             }
229              
230             /******************************************************************************/
231             /**
232             Encrypts a block of text with LTC_RC2
233             @param pt The input plaintext (8 bytes)
234             @param ct The output ciphertext (8 bytes)
235             @param skey The key as scheduled
236             @return CRYPT_OK if successful
237             */
238 0           static void psRc2EncryptBlock(const unsigned char *pt, unsigned char *ct,
239             psRc2Key_t *ctx)
240             {
241             uint32_t *xkey;
242             uint32_t x76, x54, x32, x10, i;
243              
244 0           xkey = ctx->xkey;
245 0           x76 = ((uint32_t) pt[7] << 8) + (uint32_t) pt[6];
246 0           x54 = ((uint32_t) pt[5] << 8) + (uint32_t) pt[4];
247 0           x32 = ((uint32_t) pt[3] << 8) + (uint32_t) pt[2];
248 0           x10 = ((uint32_t) pt[1] << 8) + (uint32_t) pt[0];
249              
250 0 0         for (i = 0; i < 16; i++)
251             {
252 0           x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4 * i + 0]) & 0xFFFF;
253 0           x10 = ((x10 << 1) | (x10 >> 15));
254              
255 0           x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4 * i + 1]) & 0xFFFF;
256 0           x32 = ((x32 << 2) | (x32 >> 14));
257              
258 0           x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4 * i + 2]) & 0xFFFF;
259 0           x54 = ((x54 << 3) | (x54 >> 13));
260              
261 0           x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4 * i + 3]) & 0xFFFF;
262 0           x76 = ((x76 << 5) | (x76 >> 11));
263              
264 0 0         if (i == 4 || i == 10)
    0          
265             {
266 0           x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
267 0           x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
268 0           x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
269 0           x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
270             }
271             }
272              
273 0           ct[0] = (unsigned char) x10;
274 0           ct[1] = (unsigned char) (x10 >> 8);
275 0           ct[2] = (unsigned char) x32;
276 0           ct[3] = (unsigned char) (x32 >> 8);
277 0           ct[4] = (unsigned char) x54;
278 0           ct[5] = (unsigned char) (x54 >> 8);
279 0           ct[6] = (unsigned char) x76;
280 0           ct[7] = (unsigned char) (x76 >> 8);
281 0           }
282              
283             /******************************************************************************/
284             /**
285             Decrypts a block of text with LTC_RC2
286             @param ct The input ciphertext (8 bytes)
287             @param pt The output plaintext (8 bytes)
288             @param skey The key as scheduled
289             @return CRYPT_OK if successful
290             */
291 1924           static void psRc2DecryptBlock(const unsigned char *ct, unsigned char *pt,
292             psRc2Key_t *ctx)
293             {
294             uint32_t x76, x54, x32, x10;
295             uint32_t *xkey;
296             int i;
297              
298 1924           xkey = ctx->xkey;
299              
300 1924           x76 = ((uint32_t) ct[7] << 8) + (uint32_t) ct[6];
301 1924           x54 = ((uint32_t) ct[5] << 8) + (uint32_t) ct[4];
302 1924           x32 = ((uint32_t) ct[3] << 8) + (uint32_t) ct[2];
303 1924           x10 = ((uint32_t) ct[1] << 8) + (uint32_t) ct[0];
304              
305 32708 100         for (i = 15; i >= 0; i--)
306             {
307 30784 100         if (i == 4 || i == 10)
    100          
308             {
309 3848           x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
310 3848           x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
311 3848           x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
312 3848           x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
313             }
314              
315 30784           x76 = ((x76 << 11) | (x76 >> 5));
316 30784           x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4 * i + 3])) & 0xFFFF;
317              
318 30784           x54 = ((x54 << 13) | (x54 >> 3));
319 30784           x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4 * i + 2])) & 0xFFFF;
320              
321 30784           x32 = ((x32 << 14) | (x32 >> 2));
322 30784           x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4 * i + 1])) & 0xFFFF;
323              
324 30784           x10 = ((x10 << 15) | (x10 >> 1));
325 30784           x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4 * i + 0])) & 0xFFFF;
326             }
327              
328 1924           pt[0] = (unsigned char) x10;
329 1924           pt[1] = (unsigned char) (x10 >> 8);
330 1924           pt[2] = (unsigned char) x32;
331 1924           pt[3] = (unsigned char) (x32 >> 8);
332 1924           pt[4] = (unsigned char) x54;
333 1924           pt[5] = (unsigned char) (x54 >> 8);
334 1924           pt[6] = (unsigned char) x76;
335 1924           pt[7] = (unsigned char) (x76 >> 8);
336 1924           }
337              
338             #endif /* USE_RC2 */
339              
340             /******************************************************************************/
341