gcrypt/idea.c

Mon, 17 Sep 2012 19:10:10 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 17 Sep 2012 19:10:10 +0200
changeset 689
9fe04d4d4e5a
permissions
-rw-r--r--

Update to new version of vendor software although Oracle fails to deliver.
More specifically, newer db(3) patch revisions exist but Oracle has
removed them from the canonical download server URI for Berkely DB.

michael@107 1 #include <config.h>
michael@107 2 #include <stdio.h>
michael@107 3 #include <stdlib.h>
michael@107 4 #include <string.h> /* for memcmp() */
michael@107 5 #include <assert.h>
michael@107 6
michael@107 7 #include "types.h" /* for byte and u32 typedefs */
michael@107 8 #include "g10lib.h"
michael@107 9 #include "cipher.h"
michael@107 10
michael@107 11 /* configuration stuff */
michael@107 12 #ifdef __alpha__
michael@107 13 #define SIZEOF_UNSIGNED_LONG 8
michael@107 14 #else
michael@107 15 #define SIZEOF_UNSIGNED_LONG 4
michael@107 16 #endif
michael@107 17
michael@107 18 #if defined(__mc68000__) || defined (__sparc__) || defined (__PPC__) \
michael@107 19 || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__)) ) \
michael@107 20 || defined(__powerpc__) \
michael@107 21 || defined(__hpux__) /* should be replaced by the Macro for the PA */
michael@107 22 #define BIG_ENDIAN_HOST 1
michael@107 23 #else
michael@107 24 #define LITTLE_ENDIAN_HOST 1
michael@107 25 #endif
michael@107 26
michael@107 27 #ifndef DIM
michael@107 28 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
michael@107 29 #define DIMof(type,member) DIM(((type *)0)->member)
michael@107 30 #endif
michael@107 31
michael@107 32 /* imports */
michael@107 33 void g10_log_fatal( const char *fmt, ... );
michael@107 34
michael@107 35
michael@107 36 /* local stuff */
michael@107 37
michael@107 38 #define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f))
michael@107 39 #define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f))
michael@107 40
michael@107 41 #define IDEA_KEYSIZE 16
michael@107 42 #define IDEA_BLOCKSIZE 8
michael@107 43 #define IDEA_ROUNDS 8
michael@107 44 #define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
michael@107 45
michael@107 46 typedef struct {
michael@107 47 u16 ek[IDEA_KEYLEN];
michael@107 48 u16 dk[IDEA_KEYLEN];
michael@107 49 int have_dk;
michael@107 50 } IDEA_context;
michael@107 51
michael@107 52 static u16
michael@107 53 mul_inv( u16 x )
michael@107 54 {
michael@107 55 u16 t0, t1;
michael@107 56 u16 q, y;
michael@107 57
michael@107 58 if( x < 2 )
michael@107 59 return x;
michael@107 60 t1 = 0x10001L / x;
michael@107 61 y = 0x10001L % x;
michael@107 62 if( y == 1 )
michael@107 63 return (1-t1) & 0xffff;
michael@107 64
michael@107 65 t0 = 1;
michael@107 66 do {
michael@107 67 q = x / y;
michael@107 68 x = x % y;
michael@107 69 t0 += q * t1;
michael@107 70 if( x == 1 )
michael@107 71 return t0;
michael@107 72 q = y / x;
michael@107 73 y = y % x;
michael@107 74 t1 += q * t0;
michael@107 75 } while( y != 1 );
michael@107 76 return (1-t1) & 0xffff;
michael@107 77 }
michael@107 78
michael@107 79 static void
michael@107 80 cipher( byte *outbuf, const byte *inbuf, u16 *key )
michael@107 81 {
michael@107 82 u16 x1, x2, x3,x4, s2, s3;
michael@107 83 u16 *in, *out;
michael@107 84 int r = IDEA_ROUNDS;
michael@107 85 #define MUL(x,y) \
michael@107 86 do {u16 _t16; u32 _t32; \
michael@107 87 if( (_t16 = (y)) ) { \
michael@107 88 if( (x = (x)&0xffff) ) { \
michael@107 89 _t32 = (u32)x * _t16; \
michael@107 90 x = _t32 & 0xffff; \
michael@107 91 _t16 = _t32 >> 16; \
michael@107 92 x = ((x)-_t16) + (x<_t16?1:0); \
michael@107 93 } \
michael@107 94 else { \
michael@107 95 x = 1 - _t16; \
michael@107 96 } \
michael@107 97 } \
michael@107 98 else { \
michael@107 99 x = 1 - x; \
michael@107 100 } \
michael@107 101 } while(0)
michael@107 102
michael@107 103 in = (u16*)inbuf;
michael@107 104 x1 = *in++;
michael@107 105 x2 = *in++;
michael@107 106 x3 = *in++;
michael@107 107 x4 = *in;
michael@107 108 #ifdef LITTLE_ENDIAN_HOST
michael@107 109 x1 = (x1>>8) | (x1<<8);
michael@107 110 x2 = (x2>>8) | (x2<<8);
michael@107 111 x3 = (x3>>8) | (x3<<8);
michael@107 112 x4 = (x4>>8) | (x4<<8);
michael@107 113 #endif
michael@107 114 do {
michael@107 115 MUL(x1, *key++);
michael@107 116 x2 += *key++;
michael@107 117 x3 += *key++;
michael@107 118 MUL(x4, *key++ );
michael@107 119
michael@107 120 s3 = x3;
michael@107 121 x3 ^= x1;
michael@107 122 MUL(x3, *key++);
michael@107 123 s2 = x2;
michael@107 124 x2 ^=x4;
michael@107 125 x2 += x3;
michael@107 126 MUL(x2, *key++);
michael@107 127 x3 += x2;
michael@107 128
michael@107 129 x1 ^= x2;
michael@107 130 x4 ^= x3;
michael@107 131
michael@107 132 x2 ^= s3;
michael@107 133 x3 ^= s2;
michael@107 134 } while( --r );
michael@107 135 MUL(x1, *key++);
michael@107 136 x3 += *key++;
michael@107 137 x2 += *key++;
michael@107 138 MUL(x4, *key);
michael@107 139
michael@107 140 out = (u16*)outbuf;
michael@107 141 #ifdef LITTLE_ENDIAN_HOST
michael@107 142 *out++ = (x1>>8) | (x1<<8);
michael@107 143 *out++ = (x3>>8) | (x3<<8);
michael@107 144 *out++ = (x2>>8) | (x2<<8);
michael@107 145 *out = (x4>>8) | (x4<<8);
michael@107 146 #else
michael@107 147 *out++ = x1;
michael@107 148 *out++ = x3;
michael@107 149 *out++ = x2;
michael@107 150 *out = x4;
michael@107 151 #endif
michael@107 152 #undef MUL
michael@107 153 }
michael@107 154
michael@107 155 static void
michael@107 156 expand_key( const byte *userkey, u16 *ek )
michael@107 157 {
michael@107 158 int i,j;
michael@107 159
michael@107 160 for(j=0; j < 8; j++ ) {
michael@107 161 ek[j] = (*userkey << 8) + userkey[1];
michael@107 162 userkey += 2;
michael@107 163 }
michael@107 164 for(i=0; j < IDEA_KEYLEN; j++ ) {
michael@107 165 i++;
michael@107 166 ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
michael@107 167 ek += i & 8;
michael@107 168 i &= 7;
michael@107 169 }
michael@107 170 }
michael@107 171
michael@107 172 static void
michael@107 173 invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
michael@107 174 {
michael@107 175 int i;
michael@107 176 u16 t1, t2, t3;
michael@107 177 u16 temp[IDEA_KEYLEN];
michael@107 178 u16 *p = temp + IDEA_KEYLEN;
michael@107 179
michael@107 180 t1 = mul_inv( *ek++ );
michael@107 181 t2 = -*ek++;
michael@107 182 t3 = -*ek++;
michael@107 183 *--p = mul_inv( *ek++ );
michael@107 184 *--p = t3;
michael@107 185 *--p = t2;
michael@107 186 *--p = t1;
michael@107 187
michael@107 188 for(i=0; i < IDEA_ROUNDS-1; i++ ) {
michael@107 189 t1 = *ek++;
michael@107 190 *--p = *ek++;
michael@107 191 *--p = t1;
michael@107 192
michael@107 193 t1 = mul_inv( *ek++ );
michael@107 194 t2 = -*ek++;
michael@107 195 t3 = -*ek++;
michael@107 196 *--p = mul_inv( *ek++ );
michael@107 197 *--p = t2;
michael@107 198 *--p = t3;
michael@107 199 *--p = t1;
michael@107 200 }
michael@107 201 t1 = *ek++;
michael@107 202 *--p = *ek++;
michael@107 203 *--p = t1;
michael@107 204
michael@107 205 t1 = mul_inv( *ek++ );
michael@107 206 t2 = -*ek++;
michael@107 207 t3 = -*ek++;
michael@107 208 *--p = mul_inv( *ek++ );
michael@107 209 *--p = t3;
michael@107 210 *--p = t2;
michael@107 211 *--p = t1;
michael@107 212 memcpy(dk, temp, sizeof(temp) );
michael@107 213 memset(temp, 0, sizeof(temp) ); /* burn temp */
michael@107 214 }
michael@107 215
michael@107 216 static int
michael@107 217 do_idea_setkey( IDEA_context *c, const byte *key, unsigned int keylen )
michael@107 218 {
michael@107 219 assert(keylen == 16);
michael@107 220 c->have_dk = 0;
michael@107 221 expand_key( key, c->ek );
michael@107 222 invert_key( c->ek, c->dk );
michael@107 223 return 0;
michael@107 224 }
michael@107 225
michael@107 226 static gcry_err_code_t
michael@107 227 idea_setkey (void *context, const byte *key, unsigned int keylen)
michael@107 228 {
michael@107 229 IDEA_context *ctx = context;
michael@107 230 int rc = do_idea_setkey (ctx, key, keylen);
michael@107 231 _gcry_burn_stack (23+6*sizeof(void*));
michael@107 232 return rc;
michael@107 233 }
michael@107 234
michael@107 235 static void
michael@107 236 do_idea_encrypt( IDEA_context *c, byte *outbuf, const byte *inbuf )
michael@107 237 {
michael@107 238 cipher( outbuf, inbuf, c->ek );
michael@107 239 }
michael@107 240
michael@107 241 static void
michael@107 242 idea_encrypt (void *context, byte *out, const byte *in)
michael@107 243 {
michael@107 244 IDEA_context *ctx = context;
michael@107 245 do_idea_encrypt (ctx, out, in);
michael@107 246 _gcry_burn_stack (24+3*sizeof (void*));
michael@107 247 }
michael@107 248
michael@107 249 static void
michael@107 250 do_idea_decrypt( IDEA_context *c, byte *outbuf, const byte *inbuf )
michael@107 251 {
michael@107 252 if( !c->have_dk ) {
michael@107 253 c->have_dk = 1;
michael@107 254 invert_key( c->ek, c->dk );
michael@107 255 }
michael@107 256 cipher( outbuf, inbuf, c->dk );
michael@107 257 }
michael@107 258
michael@107 259 static void
michael@107 260 idea_decrypt (void *context, byte *out, const byte *in)
michael@107 261 {
michael@107 262 IDEA_context *ctx = context;
michael@107 263
michael@107 264 do_idea_decrypt (ctx, out, in);
michael@107 265 _gcry_burn_stack (24+3*sizeof (void*));
michael@107 266 }
michael@107 267
michael@107 268 gcry_cipher_spec_t _gcry_cipher_spec_idea =
michael@107 269 {
michael@107 270 "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128, sizeof (IDEA_context),
michael@107 271 idea_setkey, idea_encrypt, idea_decrypt,
michael@107 272 };

mercurial