Mon, 28 Mar 2011 19:41:02 +0200
Completely rework package including...
Simpify 64-bit -fPIC logic, instruct make to build in parallel,
force error condition on failed profile dependency, build the
standard 'bootstrap' target as suggested, correct grammar, wording,
and punctuation in general, upgrade to latest upstream vendor version,
rearrange package dependencies mpc, mpfr, and gmp, correct buildconf
thanks to new lto-plugin forced, avoid failed platform specific stage
comparison, adjust patch code to reflect new version update, and most
importantly adjust optimization flags to platform. Please note that
block 'correct hardcoded paths' is likely no yet complete.
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 | }; |