]> git.stg.codes - ssmd.git/blob - 3rdparty/snmp++/src/idea.cpp
Initial adding
[ssmd.git] / 3rdparty / snmp++ / src / idea.cpp
1 /*_############################################################################
2   _## 
3   _##  idea.cpp  
4   _##
5   _##  SNMP++v3.2.25
6   _##  -----------------------------------------------
7   _##  Copyright (c) 2001-2010 Jochen Katz, Frank Fock
8   _##
9   _##  This software is based on SNMP++2.6 from Hewlett Packard:
10   _##  
11   _##    Copyright (c) 1996
12   _##    Hewlett-Packard Company
13   _##  
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. 
25   _##  
26   _##  Stuttgart, Germany, Thu Sep  2 00:07:47 CEST 2010 
27   _##  
28   _##########################################################################*/
29 char idea_cpp_version[]="#(@) SNMP++ $Id: idea.cpp 43 2004-03-03 23:11:21Z katz $";
30 /*
31
32 idea.c
33
34 Author: Tatu Ylonen <ylo@cs.hut.fi>
35
36 Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
37                    All rights reserved
38
39 Created: Sun Jun 25 02:59:39 1995 ylo
40
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.
45
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.
48
49 */
50
51 //#include "snmp_pp/includes.h"
52 //#include "snmp_pp/getput.h"
53 #include "snmp_pp/idea.h"
54 #include <string.h>
55
56 #ifdef SNMP_PP_NAMESPACE
57 namespace Snmp_pp {
58 #endif
59
60 #ifdef _USE_IDEA
61
62 /* Sets idea key for encryption. */
63
64 void idea_set_key(IDEAContext *c, const unsigned char key[16])
65 {
66   int i;
67   word16 *keys;
68
69   /* Get pointer to the keys. */
70   keys = c->key_schedule;
71
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);
75
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++)
80     {
81       if ((i & 7) == 0)
82         keys += 8;
83       keys[i & 7] = ((keys[((i + 1) & 7) - 8] << 9) |
84                      (keys[((i + 2) & 7) - 8] >> 7)) & 0xffff;
85     }
86 }
87
88 /* Destroys any sensitive data in the context. */
89
90 void idea_destroy_context(IDEAContext *c)
91 {
92   memset(&c, 0, sizeof(c));
93 }
94
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.
99    */
100
101 static inline word32 mulop(word32 a, word32 b)
102 {
103   word32 ab = a * b;
104   if (ab != 0)
105     {
106       word32 lo = ab & 0xffff;
107       word32 hi = (ab >> 16) & 0xffff;
108       return (lo - hi) + (lo < hi);
109     }
110   if (a == 0)
111     return 1 - b;
112   return  1 - a;
113 }
114
115 /* Performs the IDEA cipher transform on a block of data. */
116
117 void idea_transform(IDEAContext *c, word32 l, word32 r, word32 *output)
118 {
119   unsigned int round;
120   word16 *keys;
121   word32 t1, t2, x1, x2, x3, x4;
122
123   keys = c->key_schedule;
124   x1 = l >> 16;
125   x2 = l;
126   x3 = r >> 16;
127   x4 = r;
128   for (round = 0; round < 8; round++)
129     {
130       x1 = mulop(x1 & 0xffff, keys[0]);
131       x3 = x3 + keys[2];
132       x4 = mulop(x4 & 0xffff, keys[3]);
133       x2 = x2 + keys[1];
134       t1 = x1 ^ x3;
135       t2 = x2 ^ x4;
136       t1 = mulop(t1 & 0xffff, keys[4]);
137       t2 = t1 + t2;
138       t2 = mulop(t2 & 0xffff, keys[5]);
139       t1 = t1 + t2;
140       x1 = x1 ^ t2;
141       x4 = x4 ^ t1;
142       t1 = t1 ^ x2;
143       x2 = t2 ^ x3;
144       x3 = t1;
145       keys += 6;
146     }
147
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);
154 }
155
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
159    encryption. */
160
161 void idea_cfb_encrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,
162                       const unsigned char *src, unsigned int len)
163 {
164   word32 iv0, iv1, out[2];
165   unsigned int i;
166
167   iv0 = GET_32BIT(iv);
168   iv1 = GET_32BIT(iv + 4);
169
170   for (i = 0; i < len; i += 8)
171     {
172       idea_transform(c, iv0, iv1, out);
173       iv0 = out[0] ^ GET_32BIT(src + i);
174       iv1 = out[1] ^ GET_32BIT(src + i + 4);
175       if (i + 8 <= len)
176         {
177           PUT_32BIT(dest + i, iv0);
178           PUT_32BIT(dest + i + 4, iv1);
179         }
180       else
181         {
182           switch (len - i)
183             {
184             case 7:
185               dest[i + 6] = iv1 >> 8;
186               /*FALLTHROUGH*/
187             case 6:
188               dest[i + 5] = iv1 >> 16;
189               /*FALLTHROUGH*/
190             case 5:
191               dest[i + 4] = iv1 >> 24;
192               /*FALLTHROUGH*/
193             case 4:
194               dest[i + 3] = iv0;
195               /*FALLTHROUGH*/
196             case 3:
197               dest[i + 2] = iv0 >> 8;
198               /*FALLTHROUGH*/
199             case 2:
200               dest[i + 1] = iv0 >> 16;
201               /*FALLTHROUGH*/
202             case 1:
203               dest[i] = iv0 >> 24;
204               /*FALLTHROUGH*/
205             }
206         }
207     }
208   PUT_32BIT(iv, iv0);
209   PUT_32BIT(iv + 4, iv1);
210 }
211
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
215    decryption. */
216
217 void idea_cfb_decrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,
218                       const unsigned char *src, unsigned int len)
219 {
220   word32 iv0, iv1, out[2], plain0, plain1;
221   unsigned int i;
222
223   iv0 = GET_32BIT(iv);
224   iv1 = GET_32BIT(iv + 4);
225
226   for (i = 0; i < len; i += 8)
227     {
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;
233       if (i + 8 <= len)
234         {
235           PUT_32BIT(dest + i, plain0);
236           PUT_32BIT(dest + i + 4, plain1);
237         }
238       else
239         {
240           switch (len - i)
241             {
242             case 7:
243               dest[i + 6] = plain1 >> 8;
244               /*FALLTHROUGH*/
245             case 6:
246               dest[i + 5] = plain1 >> 16;
247               /*FALLTHROUGH*/
248             case 5:
249               dest[i + 4] = plain1 >> 24;
250               /*FALLTHROUGH*/
251             case 4:
252               dest[i + 3] = plain0;
253               /*FALLTHROUGH*/
254             case 3:
255               dest[i + 2] = plain0 >> 8;
256               /*FALLTHROUGH*/
257             case 2:
258               dest[i + 1] = plain0 >> 16;
259               /*FALLTHROUGH*/
260             case 1:
261               dest[i] = plain0 >> 24;
262               /*FALLTHROUGH*/
263             }
264         }
265     }
266   PUT_32BIT(iv, iv0);
267   PUT_32BIT(iv + 4, iv1);
268 }
269
270 #endif
271
272 #ifdef SNMP_PP_NAMESPACE
273 }; // end of namespace Snmp_pp
274 #endif