Sun, 03 Apr 2011 13:34:55 +0200
Correct and improve several packaging aspects including...
Correct datadir path for python modules, correct jar(1) path for
building libgcj classes, strip libexecdir path of version numbers,
improve name of oblbld build path, clean whitespace from as(1) and
ld(1) GNU detection, remove seemingly discarded '--with-local-prefix'
configure argument, and correct hardcoded lto plugin libtool archive
dependency information.
Most importantly, correct IA32 architecture detection logic in
config.gcc to correctly emit SSE2 instructions conditionally, leading
to the removal of all '-march' bootstrap options and replacement with
unconditional (for IA32/AMD64) '-mtune=native' options. Comments and
buildtime warnings are corrected appropriately. In theory these changes
cause a more portable, orthoganal, and optimal bootstrap to be built.
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 | }; |