1 /*
2 Copyright (C) 2008,2009 Luigi Auriemma
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 http://www.gnu.org/licenses/gpl-2.0.txt
15 */
16 // modified by Luigi Auriemma for emulating the shameful customizations of MagicISO
17 /* idea.c - IDEA function
18 * Copyright (c) 1997,1998,1999 by Werner Koch (dd9jn)
19 ************************************************************************
20 * ATTENTION: The used algorithm is patented and may need a license
21 for any use. See below for more information.
22 ************************************************************************
23 *
24 * Permission is hereby granted, free of charge, to any person obtaining a
25 * copy of this software and associated documentation files (the "Software"),
26 * to deal in the Software without restriction, including without limitation
27 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
28 * and/or sell copies of the Software, and to permit persons to whom the
29 * Software is furnished to do so, subject to the following conditions:
30 *
31 * The above copyright notice and this permission notice shall be included in
32 * all copies or substantial portions of the Software.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
37 * WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 *
41 * Except as contained in this notice, the name of Werner Koch shall not be
42 * used in advertising or otherwise to promote the sale, use or other dealings
43 * in this Software without prior written authorization from Werner Koch.
44 */
45
46 /*--------------------------------------------------------------
47 The code herein has been taken from:
48 Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
49 ISBN 0-471-11709-9. .
50
51 The IDEA algorithm is patented by Ascom Systec Ltd. of CH-5506 Maegenwil,
52 Switzerland, who allow it to be used on a royalty-free basis for certain
53 non-profit applications. Commercial users must obtain a license from the
54 company in order to use IDEA. IDEA may be used on a royalty-free basis under
55 the following conditions:
56
57 Free use for private purposes:
58
59 The free use of software containing the algorithm is strictly limited to non
60 revenue generating data transfer between private individuals, ie not serving
61 commercial purposes. Requests by freeware developers to obtain a
62 royalty-free license to spread an application program containing the
63 algorithm for non-commercial purposes must be directed to Ascom.
64
65 Special offer for shareware developers:
66
67 There is a special waiver for shareware developers. Such waiver eliminates
68 the upfront fees as well as royalties for the first US$10,000 gross sales of
69 a product containing the algorithm if and only if:
70
71 1. The product is being sold for a minimum of US$10 and a maximum of US$50.
72 2. The source code for the shareware is available to the public.
73
74 Special conditions for research projects:
75
76 The use of the algorithm in research projects is free provided that it serves
77 the purpose of such project and within the project duration. Any use of the
78 algorithm after the termination of a project including activities resulting
79 from a project and for purposes not directly related to the project requires
80 a license.
81
82 Ascom Tech requires the following notice to be included for freeware
83 products:
84
85 This software product contains the IDEA algorithm as described and claimed in
86 US patent 5,214,703, EPO patent 0482154 (covering Austria, France, Germany,
87 Italy, the Netherlands, Spain, Sweden, Switzerland, and the UK), and Japanese
88 patent application 508119/1991, "Device for the conversion of a digital block
89 and use of same" (hereinafter referred to as "the algorithm"). Any use of
90 the algorithm for commercial purposes is thus subject to a license from Ascom
91 Systec Ltd. of CH-5506 Maegenwil (Switzerland), being the patentee and sole
92 owner of all rights, including the trademark IDEA.
93
94 Commercial purposes shall mean any revenue generating purpose including but
95 not limited to:
96
97 i) Using the algorithm for company internal purposes (subject to a site
98 license).
99
100 ii) Incorporating the algorithm into any software and distributing such
101 software and/or providing services relating thereto to others (subject to
102 a product license).
103
104 iii) Using a product containing the algorithm not covered by an IDEA license
105 (subject to an end user license).
106
107 All such end user license agreements are available exclusively from Ascom
108 Systec Ltd and may be requested via the WWW at http://www.ascom.ch/systec or
109 by email to idea@ascom.ch.
110
111 Use other than for commercial purposes is strictly limited to non-revenue
112 generating data transfer between private individuals. The use by government
113 agencies, non-profit organizations, etc is considered as use for commercial
114 purposes but may be subject to special conditions. Any misuse will be
115 prosecuted.
116 -------------------------------------------------------------------*/
117
118 /* How to compile:
119 *
120 gcc -Wall -O2 -shared -fPIC -o idea idea.c
121 */
122
123
124 #include <stdio.h>
125 #include <stdlib.h>
126 #include <stdint.h>
127 #include <string.h>
128
129 /* configuration stuff */
130 #ifdef __alpha__
131 #define SIZEOF_UNSIGNED_LONG 8
132 #else
133 #define SIZEOF_UNSIGNED_LONG 4
134 #endif
135
136
137
138 typedef unsigned char byte;
139 typedef uint16_t u16;
140 typedef uint32_t u32;
141
142 /* end configurable stuff */
143
144 #ifndef DIM
145 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
146 #define DIMof(type,member) DIM(((type *)0)->member)
147 #endif
148
149 /* imports */
150 void g10_log_fatal( const char *fmt, ... );
151
152
153 /* local stuff */
154
155 #define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f))
156 #define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f))
157
158 #define IDEA_KEYSIZE 16
159 #define IDEA_BLOCKSIZE 8
160 #define IDEA_ROUNDS 8
161 #define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
162
163 typedef struct {
164 u16 ek[IDEA_KEYLEN];
165 u16 dk[IDEA_KEYLEN];
166 int have_dk;
167 } IDEA_context;
168
169
170 int do_setkey( IDEA_context *c, byte *key, unsigned keylen );
171 void encrypt_block( IDEA_context *bc, byte *outbuf, byte *inbuf );
172 void decrypt_block( IDEA_context *bc, byte *outbuf, byte *inbuf );
173
174
175
176 u16
mul_inv(u16 x)177 mul_inv( u16 x )
178 {
179 u16 t0, t1;
180 u16 q, y;
181
182 if( x < 2 )
183 return x;
184 t1 = 0x10001L / x;
185 y = 0x10001L % x;
186 if( y == 1 )
187 return (1-t1) & 0xffff;
188
189 t0 = 1;
190 do {
191 q = x / y;
192 x = x % y;
193 t0 += q * t1;
194 if( x == 1 )
195 return t0;
196 q = y / x;
197 y = y % x;
198 t1 += q * t0;
199 } while( y != 1 );
200 return (1-t1) & 0xffff;
201 }
202
203
204
205 void
expand_key(byte * userkey,u16 * ek)206 expand_key( byte *userkey, u16 *ek )
207 {
208 int i,j;
209
210 for(j=0; j < 8; j++ ) {
211 ek[j] = (*userkey << 8) + userkey[1];
212 userkey += 2;
213 }
214 for(i=0; j < IDEA_KEYLEN; j++ ) {
215 i++;
216 ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
217 ek[i+7] ^= 0x28fc;
218 ek += i & 8;
219 i &= 7;
220 }
221 }
222
223
224 void
invert_key(u16 * ek,u16 dk[IDEA_KEYLEN])225 invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
226 {
227 int i;
228 u16 t1, t2, t3;
229 u16 temp[IDEA_KEYLEN];
230 u16 *p = temp + IDEA_KEYLEN;
231
232 t1 = mul_inv( *ek++ );
233 t2 = -*ek++;
234 t3 = -*ek++;
235 *--p = mul_inv( *ek++ );
236 *--p = t3;
237 *--p = t2;
238 *--p = t1;
239
240 for(i=0; i < IDEA_ROUNDS-1; i++ ) {
241 t1 = *ek++;
242 *--p = *ek++;
243 *--p = t1;
244
245 t1 = mul_inv( *ek++ );
246 t2 = -*ek++;
247 t3 = -*ek++;
248 *--p = mul_inv( *ek++ );
249 *--p = t2;
250 *--p = t3;
251 *--p = t1;
252 }
253 t1 = *ek++;
254 *--p = *ek++;
255 *--p = t1;
256
257 t1 = mul_inv( *ek++ );
258 t2 = -*ek++;
259 t3 = -*ek++;
260 *--p = mul_inv( *ek++ );
261 *--p = t3;
262 *--p = t2;
263 *--p = t1;
264 memcpy(dk, temp, sizeof(temp) );
265 }
266
267
268 void
cipher(byte * outbuf,byte * inbuf,u16 * key)269 cipher( byte *outbuf, byte *inbuf, u16 *key )
270 {
271 u16 x1, x2, x3,x4, s2, s3;
272 u16 *in, *out;
273 int r = IDEA_ROUNDS;
274 #define MUL(x,y) \
275 do {u16 _t16; u32 _t32; \
276 if( (_t16 = (y)) ) { \
277 if( (x = (x)&0xffff) ) { \
278 _t32 = (u32)x * _t16; \
279 x = _t32 & 0xffff; \
280 _t16 = _t32 >> 16; \
281 x = ((x)-_t16) + (x<_t16?1:0); \
282 } \
283 else { \
284 x = 1 - _t16; \
285 } \
286 } \
287 else { \
288 x = 1 - x; \
289 } \
290 } while(0)
291
292 in = (u16*)inbuf;
293 x1 = *in++;
294 x2 = *in++;
295 x3 = *in++;
296 x4 = *in;
297 do {
298 MUL(x1, *key++);
299 x2 += *key++;
300 x3 += *key++;
301 MUL(x4, *key++ );
302
303 s3 = x3;
304 x3 ^= x1;
305 MUL(x3, *key++);
306 s2 = x2;
307 x2 ^=x4;
308 x2 += x3;
309 MUL(x2, *key++);
310 x3 += x2;
311
312 x1 ^= x2;
313 x4 ^= x3;
314
315 x2 ^= s3;
316 x3 ^= s2;
317 } while( --r );
318 MUL(x1, *key++);
319 x3 += *key++;
320 x2 += *key++;
321 MUL(x4, *key);
322
323 out = (u16*)outbuf;
324 *out++ = x1;
325 *out++ = x3;
326 *out++ = x2;
327 *out = x4;
328 #undef MUL
329 }
330
331
332 int
do_setkey(IDEA_context * c,byte * key,unsigned keylen)333 do_setkey( IDEA_context *c, byte *key, unsigned keylen )
334 {
335 c->have_dk = 0;
336 expand_key( key, c->ek );
337 invert_key( c->ek, c->dk );
338 return 0;
339 }
340
341 void
encrypt_block(IDEA_context * c,byte * outbuf,byte * inbuf)342 encrypt_block( IDEA_context *c, byte *outbuf, byte *inbuf )
343 {
344 cipher( outbuf, inbuf, c->ek );
345 }
346
347 void
decrypt_block(IDEA_context * c,byte * outbuf,byte * inbuf)348 decrypt_block( IDEA_context *c, byte *outbuf, byte *inbuf )
349 {
350 if( !c->have_dk ) {
351 c->have_dk = 1;
352 invert_key( c->ek, c->dk );
353 }
354 cipher( outbuf, inbuf, c->dk );
355 }
356