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