1 /*_############################################################################
6 _## -----------------------------------------------
7 _## Copyright (c) 2001-2010 Jochen Katz, Frank Fock
9 _## This software is based on SNMP++2.6 from Hewlett Packard:
11 _## Copyright (c) 1996
12 _## Hewlett-Packard Company
14 _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
15 _## Permission to use, copy, modify, distribute and/or sell this software
16 _## and/or its documentation is hereby granted without fee. User agrees
17 _## to display the above copyright notice and this license notice in all
18 _## copies of the software and any documentation of the software. User
19 _## agrees to assume all liability for the use of the software;
20 _## Hewlett-Packard and Jochen Katz make no representations about the
21 _## suitability of this software for any purpose. It is provided
22 _## "AS-IS" without warranty of any kind, either express or implied. User
23 _## hereby grants a royalty-free license to any and all derivatives based
24 _## upon this software code base.
26 _## Stuttgart, Germany, Thu Sep 2 00:07:47 CEST 2010
28 _##########################################################################*/
29 char idea_cpp_version[]="#(@) SNMP++ $Id: idea.cpp 43 2004-03-03 23:11:21Z katz $";
34 Author: Tatu Ylonen <ylo@cs.hut.fi>
36 Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
39 Created: Sun Jun 25 02:59:39 1995 ylo
41 This code is based on Xuejia Lai: On the Design and Security of Block
42 Ciphers, ETH Series in Information Processing, vol. 1, Hartung-Gorre
43 Verlag, Konstanz, Switzerland, 1992. Another source was Bruce
44 Schneier: Applied Cryptography, John Wiley & Sons, 1994.
46 The IDEA mathematical formula may be covered by one or more of the
47 following patents: PCT/CH91/00117, EP 0 482 154 B1, US Pat. 5,214,703.
51 //#include "snmp_pp/includes.h"
52 //#include "snmp_pp/getput.h"
53 #include "snmp_pp/idea.h"
56 #ifdef SNMP_PP_NAMESPACE
62 /* Sets idea key for encryption. */
64 void idea_set_key(IDEAContext *c, const unsigned char key[16])
69 /* Get pointer to the keys. */
70 keys = c->key_schedule;
72 /* Keys for the first round are directly taken from the user-supplied key. */
73 for (i = 0; i < 8; i++)
74 keys[i] = (word16)GET_16BIT(key + 2 * i);
76 /* Each round uses the key of the previous key, rotated to the left by 25
77 bits. The last four keys (output transform) are the first four keys
78 from what would be the ninth round. */
79 for (i = 8; i < 52; i++)
83 keys[i & 7] = ((keys[((i + 1) & 7) - 8] << 9) |
84 (keys[((i + 2) & 7) - 8] >> 7)) & 0xffff;
88 /* Destroys any sensitive data in the context. */
90 void idea_destroy_context(IDEAContext *c)
92 memset(&c, 0, sizeof(c));
95 /* Performs the "multiplication" operation of IDEA: returns a*b mod 65537,
96 where a and b are first converted to 65536 if they are zero, and result
97 65536 is converted to zero. Both inputs should be less than 65536.
98 Only the lower 16 bits of result are significant; other bits are garbage.
101 static inline word32 mulop(word32 a, word32 b)
106 word32 lo = ab & 0xffff;
107 word32 hi = (ab >> 16) & 0xffff;
108 return (lo - hi) + (lo < hi);
115 /* Performs the IDEA cipher transform on a block of data. */
117 void idea_transform(IDEAContext *c, word32 l, word32 r, word32 *output)
121 word32 t1, t2, x1, x2, x3, x4;
123 keys = c->key_schedule;
128 for (round = 0; round < 8; round++)
130 x1 = mulop(x1 & 0xffff, keys[0]);
132 x4 = mulop(x4 & 0xffff, keys[3]);
136 t1 = mulop(t1 & 0xffff, keys[4]);
138 t2 = mulop(t2 & 0xffff, keys[5]);
148 x1 = mulop(x1 & 0xffff, keys[0]);
149 x3 = (x2 + keys[2]) & 0xffff;
150 x2 = t1 + keys[1]; /* t1 == old x3 */
151 x4 = mulop(x4 & 0xffff, keys[3]);
152 output[0] = (x1 << 16) | (x2 & 0xffff);
153 output[1] = (x3 << 16) | (x4 & 0xffff);
156 /* Encrypts len bytes from src to dest in CFB mode. Len need not be a multiple
157 of 8; if it is not, iv at return will contain garbage.
158 Otherwise, iv will be modified at end to a value suitable for continuing
161 void idea_cfb_encrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,
162 const unsigned char *src, unsigned int len)
164 word32 iv0, iv1, out[2];
168 iv1 = GET_32BIT(iv + 4);
170 for (i = 0; i < len; i += 8)
172 idea_transform(c, iv0, iv1, out);
173 iv0 = out[0] ^ GET_32BIT(src + i);
174 iv1 = out[1] ^ GET_32BIT(src + i + 4);
177 PUT_32BIT(dest + i, iv0);
178 PUT_32BIT(dest + i + 4, iv1);
185 dest[i + 6] = iv1 >> 8;
188 dest[i + 5] = iv1 >> 16;
191 dest[i + 4] = iv1 >> 24;
197 dest[i + 2] = iv0 >> 8;
200 dest[i + 1] = iv0 >> 16;
209 PUT_32BIT(iv + 4, iv1);
212 /* Decrypts len bytes from src to dest in CFB mode. Len need not be a multiple
213 of 8; if it is not, iv at return will contain garbage.
214 Otherwise, iv will be modified at end to a value suitable for continuing
217 void idea_cfb_decrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,
218 const unsigned char *src, unsigned int len)
220 word32 iv0, iv1, out[2], plain0, plain1;
224 iv1 = GET_32BIT(iv + 4);
226 for (i = 0; i < len; i += 8)
228 idea_transform(c, iv0, iv1, out);
229 iv0 = GET_32BIT(src + i);
230 iv1 = GET_32BIT(src + i + 4);
231 plain0 = out[0] ^ iv0;
232 plain1 = out[1] ^ iv1;
235 PUT_32BIT(dest + i, plain0);
236 PUT_32BIT(dest + i + 4, plain1);
243 dest[i + 6] = plain1 >> 8;
246 dest[i + 5] = plain1 >> 16;
249 dest[i + 4] = plain1 >> 24;
252 dest[i + 3] = plain0;
255 dest[i + 2] = plain0 >> 8;
258 dest[i + 1] = plain0 >> 16;
261 dest[i] = plain0 >> 24;
267 PUT_32BIT(iv + 4, iv1);
272 #ifdef SNMP_PP_NAMESPACE
273 }; // end of namespace Snmp_pp