Sat, 21 Feb 2009 16:39:01 +0100
Patch gnupg and its dependency gcrypt to accept use of the IDEA cipher.
This effort seems to be flawed, as runtime tests of generating a
revokation certificate for a IDEA encrypted key were inconclusive.
Suspicion rests on a flawed implementation or patch logic.
gcrypt/gcrypt.patch | file | annotate | diff | comparison | revisions | |
gcrypt/gcrypt.spec | file | annotate | diff | comparison | revisions | |
gcrypt/idea.c | file | annotate | diff | comparison | revisions | |
gnupg/gnupg.patch | file | annotate | diff | comparison | revisions | |
gnupg/gnupg.spec | file | annotate | diff | comparison | revisions |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gcrypt/gcrypt.patch Sat Feb 21 16:39:01 2009 +0100 1.3 @@ -0,0 +1,41 @@ 1.4 +Index: cipher/cipher.c 1.5 +diff -Nau cipher/cipher.c.orig cipher/cipher.c 1.6 +--- cipher/cipher.c.orig 2008-09-12 15:23:37.000000000 +0200 1.7 ++++ cipher/cipher.c 2009-02-18 19:07:30.388253084 +0100 1.8 +@@ -97,6 +97,10 @@ 1.9 + { &_gcry_cipher_spec_rfc2268_40, 1.10 + &dummy_extra_spec, GCRY_CIPHER_RFC2268_40 }, 1.11 + #endif 1.12 ++#if USE_IDEA 1.13 ++ { &_gcry_cipher_spec_idea, 1.14 ++ &dummy_extra_spec, GCRY_CIPHER_IDEA }, 1.15 ++#endif 1.16 + #if USE_SEED 1.17 + { &_gcry_cipher_spec_seed, 1.18 + &dummy_extra_spec, GCRY_CIPHER_SEED }, 1.19 +Index: src/cipher.h 1.20 +diff -Nau src/cipher.h.orig src/cipher.h 1.21 +--- src/cipher.h.orig 2008-09-03 12:04:42.000000000 +0200 1.22 ++++ src/cipher.h 2009-02-18 19:09:20.193397539 +0100 1.23 +@@ -105,6 +105,7 @@ 1.24 + extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128; 1.25 + extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; 1.26 + extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256; 1.27 ++extern gcry_cipher_spec_t _gcry_cipher_spec_idea; 1.28 + 1.29 + extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes; 1.30 + extern cipher_extra_spec_t _gcry_cipher_extraspec_aes; 1.31 +Index: tests/basic.c 1.32 +diff -Nau tests/basic.c.orig tests/basic.c 1.33 +--- tests/basic.c.orig 2008-09-18 16:35:57.000000000 +0200 1.34 ++++ tests/basic.c 2009-02-18 19:10:14.460255272 +0100 1.35 +@@ -1028,6 +1028,9 @@ 1.36 + GCRY_CIPHER_CAMELLIA192, 1.37 + GCRY_CIPHER_CAMELLIA256, 1.38 + #endif 1.39 ++#if USE_IDEA 1.40 ++ GCRY_CIPHER_IDEA, 1.41 ++#endif 1.42 + 0 1.43 + }; 1.44 + static int algos2[] = {
2.1 --- a/gcrypt/gcrypt.spec Wed Feb 18 16:40:58 2009 +0100 2.2 +++ b/gcrypt/gcrypt.spec Sat Feb 21 16:39:01 2009 +0100 2.3 @@ -32,10 +32,15 @@ 2.4 Group: Cryptography 2.5 License: LGPL 2.6 Version: 1.4.3 2.7 -Release: 20080921 2.8 +Release: 20090106 2.9 + 2.10 +# package options 2.11 +%option with_idea no 2.12 2.13 # list of sources 2.14 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.gz 2.15 +Source1: idea.c 2.16 +Patch0: gcrypt.patch 2.17 2.18 # build information 2.19 Prefix: %{l_prefix} 2.20 @@ -57,6 +62,22 @@ 2.21 2.22 %prep 2.23 %setup -q -n libgcrypt-%{version} 2.24 + %patch -p0 2.25 +%if "%{with_idea}" == "yes" 2.26 + echo $PWD 2.27 + pwd 2.28 + echo `pwd` 2.29 + cp %{SOURCE idea.c} cipher/ 2.30 + %{l_shtool} subst \ 2.31 + -e 's;^\(EXTRA_libcipher_la_SOURCES =\);\1 idea.c;' \ 2.32 + -e 's;^\(GCRYPT_MODULES = .*[^\ \t]\)[\ \t]*$;\1 idea.lo;' \ 2.33 + -e 's;^\(GCRYPT_CIPHERS = .*[^\ \t]\)[\ \t]*$;\1 idea.lo;' \ 2.34 + -e 's;^\(LIBGCRYPT_CIPHERS = .*[^\ \t]\)[\ \t]*$;\1 idea;' \ 2.35 + cipher/Makefile.in 2.36 + %{l_shtool} subst \ 2.37 + -e 's;^\(available_ciphers="arcfour [^"][^"]*\)";\1 idea";' \ 2.38 + configure 2.39 +%endif 2.40 2.41 %build 2.42 ( echo "ac_cv_lib_pthread_pthread_create=no" 2.43 @@ -64,6 +85,9 @@ 2.44 ) >config.cache 2.45 CC="%{l_cc}" \ 2.46 CFLAGS="%{l_cflags -O}" \ 2.47 +%if "%{with_idea}" == "yes" 2.48 + CPPFLAGS="-DUSE_IDEA $CPPFLAGS" \ 2.49 +%endif 2.50 GREP="grep" \ 2.51 ./configure \ 2.52 --cache-file=./config.cache \
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/gcrypt/idea.c Sat Feb 21 16:39:01 2009 +0100 3.3 @@ -0,0 +1,272 @@ 3.4 +#include <config.h> 3.5 +#include <stdio.h> 3.6 +#include <stdlib.h> 3.7 +#include <string.h> /* for memcmp() */ 3.8 +#include <assert.h> 3.9 + 3.10 +#include "types.h" /* for byte and u32 typedefs */ 3.11 +#include "g10lib.h" 3.12 +#include "cipher.h" 3.13 + 3.14 +/* configuration stuff */ 3.15 +#ifdef __alpha__ 3.16 + #define SIZEOF_UNSIGNED_LONG 8 3.17 +#else 3.18 + #define SIZEOF_UNSIGNED_LONG 4 3.19 +#endif 3.20 + 3.21 +#if defined(__mc68000__) || defined (__sparc__) || defined (__PPC__) \ 3.22 + || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__)) ) \ 3.23 + || defined(__powerpc__) \ 3.24 + || defined(__hpux__) /* should be replaced by the Macro for the PA */ 3.25 + #define BIG_ENDIAN_HOST 1 3.26 +#else 3.27 + #define LITTLE_ENDIAN_HOST 1 3.28 +#endif 3.29 + 3.30 +#ifndef DIM 3.31 + #define DIM(v) (sizeof(v)/sizeof((v)[0])) 3.32 + #define DIMof(type,member) DIM(((type *)0)->member) 3.33 +#endif 3.34 + 3.35 +/* imports */ 3.36 +void g10_log_fatal( const char *fmt, ... ); 3.37 + 3.38 + 3.39 +/* local stuff */ 3.40 + 3.41 +#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f)) 3.42 +#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f)) 3.43 + 3.44 +#define IDEA_KEYSIZE 16 3.45 +#define IDEA_BLOCKSIZE 8 3.46 +#define IDEA_ROUNDS 8 3.47 +#define IDEA_KEYLEN (6*IDEA_ROUNDS+4) 3.48 + 3.49 +typedef struct { 3.50 + u16 ek[IDEA_KEYLEN]; 3.51 + u16 dk[IDEA_KEYLEN]; 3.52 + int have_dk; 3.53 +} IDEA_context; 3.54 + 3.55 +static u16 3.56 +mul_inv( u16 x ) 3.57 +{ 3.58 + u16 t0, t1; 3.59 + u16 q, y; 3.60 + 3.61 + if( x < 2 ) 3.62 + return x; 3.63 + t1 = 0x10001L / x; 3.64 + y = 0x10001L % x; 3.65 + if( y == 1 ) 3.66 + return (1-t1) & 0xffff; 3.67 + 3.68 + t0 = 1; 3.69 + do { 3.70 + q = x / y; 3.71 + x = x % y; 3.72 + t0 += q * t1; 3.73 + if( x == 1 ) 3.74 + return t0; 3.75 + q = y / x; 3.76 + y = y % x; 3.77 + t1 += q * t0; 3.78 + } while( y != 1 ); 3.79 + return (1-t1) & 0xffff; 3.80 +} 3.81 + 3.82 +static void 3.83 +cipher( byte *outbuf, const byte *inbuf, u16 *key ) 3.84 +{ 3.85 + u16 x1, x2, x3,x4, s2, s3; 3.86 + u16 *in, *out; 3.87 + int r = IDEA_ROUNDS; 3.88 + #define MUL(x,y) \ 3.89 + do {u16 _t16; u32 _t32; \ 3.90 + if( (_t16 = (y)) ) { \ 3.91 + if( (x = (x)&0xffff) ) { \ 3.92 + _t32 = (u32)x * _t16; \ 3.93 + x = _t32 & 0xffff; \ 3.94 + _t16 = _t32 >> 16; \ 3.95 + x = ((x)-_t16) + (x<_t16?1:0); \ 3.96 + } \ 3.97 + else { \ 3.98 + x = 1 - _t16; \ 3.99 + } \ 3.100 + } \ 3.101 + else { \ 3.102 + x = 1 - x; \ 3.103 + } \ 3.104 + } while(0) 3.105 + 3.106 + in = (u16*)inbuf; 3.107 + x1 = *in++; 3.108 + x2 = *in++; 3.109 + x3 = *in++; 3.110 + x4 = *in; 3.111 + #ifdef LITTLE_ENDIAN_HOST 3.112 + x1 = (x1>>8) | (x1<<8); 3.113 + x2 = (x2>>8) | (x2<<8); 3.114 + x3 = (x3>>8) | (x3<<8); 3.115 + x4 = (x4>>8) | (x4<<8); 3.116 + #endif 3.117 + do { 3.118 + MUL(x1, *key++); 3.119 + x2 += *key++; 3.120 + x3 += *key++; 3.121 + MUL(x4, *key++ ); 3.122 + 3.123 + s3 = x3; 3.124 + x3 ^= x1; 3.125 + MUL(x3, *key++); 3.126 + s2 = x2; 3.127 + x2 ^=x4; 3.128 + x2 += x3; 3.129 + MUL(x2, *key++); 3.130 + x3 += x2; 3.131 + 3.132 + x1 ^= x2; 3.133 + x4 ^= x3; 3.134 + 3.135 + x2 ^= s3; 3.136 + x3 ^= s2; 3.137 + } while( --r ); 3.138 + MUL(x1, *key++); 3.139 + x3 += *key++; 3.140 + x2 += *key++; 3.141 + MUL(x4, *key); 3.142 + 3.143 + out = (u16*)outbuf; 3.144 + #ifdef LITTLE_ENDIAN_HOST 3.145 + *out++ = (x1>>8) | (x1<<8); 3.146 + *out++ = (x3>>8) | (x3<<8); 3.147 + *out++ = (x2>>8) | (x2<<8); 3.148 + *out = (x4>>8) | (x4<<8); 3.149 + #else 3.150 + *out++ = x1; 3.151 + *out++ = x3; 3.152 + *out++ = x2; 3.153 + *out = x4; 3.154 + #endif 3.155 + #undef MUL 3.156 +} 3.157 + 3.158 +static void 3.159 +expand_key( const byte *userkey, u16 *ek ) 3.160 +{ 3.161 + int i,j; 3.162 + 3.163 + for(j=0; j < 8; j++ ) { 3.164 + ek[j] = (*userkey << 8) + userkey[1]; 3.165 + userkey += 2; 3.166 + } 3.167 + for(i=0; j < IDEA_KEYLEN; j++ ) { 3.168 + i++; 3.169 + ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7; 3.170 + ek += i & 8; 3.171 + i &= 7; 3.172 + } 3.173 +} 3.174 + 3.175 +static void 3.176 +invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] ) 3.177 +{ 3.178 + int i; 3.179 + u16 t1, t2, t3; 3.180 + u16 temp[IDEA_KEYLEN]; 3.181 + u16 *p = temp + IDEA_KEYLEN; 3.182 + 3.183 + t1 = mul_inv( *ek++ ); 3.184 + t2 = -*ek++; 3.185 + t3 = -*ek++; 3.186 + *--p = mul_inv( *ek++ ); 3.187 + *--p = t3; 3.188 + *--p = t2; 3.189 + *--p = t1; 3.190 + 3.191 + for(i=0; i < IDEA_ROUNDS-1; i++ ) { 3.192 + t1 = *ek++; 3.193 + *--p = *ek++; 3.194 + *--p = t1; 3.195 + 3.196 + t1 = mul_inv( *ek++ ); 3.197 + t2 = -*ek++; 3.198 + t3 = -*ek++; 3.199 + *--p = mul_inv( *ek++ ); 3.200 + *--p = t2; 3.201 + *--p = t3; 3.202 + *--p = t1; 3.203 + } 3.204 + t1 = *ek++; 3.205 + *--p = *ek++; 3.206 + *--p = t1; 3.207 + 3.208 + t1 = mul_inv( *ek++ ); 3.209 + t2 = -*ek++; 3.210 + t3 = -*ek++; 3.211 + *--p = mul_inv( *ek++ ); 3.212 + *--p = t3; 3.213 + *--p = t2; 3.214 + *--p = t1; 3.215 + memcpy(dk, temp, sizeof(temp) ); 3.216 + memset(temp, 0, sizeof(temp) ); /* burn temp */ 3.217 +} 3.218 + 3.219 +static int 3.220 +do_idea_setkey( IDEA_context *c, const byte *key, unsigned int keylen ) 3.221 +{ 3.222 + assert(keylen == 16); 3.223 + c->have_dk = 0; 3.224 + expand_key( key, c->ek ); 3.225 + invert_key( c->ek, c->dk ); 3.226 + return 0; 3.227 +} 3.228 + 3.229 +static gcry_err_code_t 3.230 +idea_setkey (void *context, const byte *key, unsigned int keylen) 3.231 +{ 3.232 + IDEA_context *ctx = context; 3.233 + int rc = do_idea_setkey (ctx, key, keylen); 3.234 + _gcry_burn_stack (23+6*sizeof(void*)); 3.235 + return rc; 3.236 +} 3.237 + 3.238 +static void 3.239 +do_idea_encrypt( IDEA_context *c, byte *outbuf, const byte *inbuf ) 3.240 +{ 3.241 + cipher( outbuf, inbuf, c->ek ); 3.242 +} 3.243 + 3.244 +static void 3.245 +idea_encrypt (void *context, byte *out, const byte *in) 3.246 +{ 3.247 + IDEA_context *ctx = context; 3.248 + do_idea_encrypt (ctx, out, in); 3.249 + _gcry_burn_stack (24+3*sizeof (void*)); 3.250 +} 3.251 + 3.252 +static void 3.253 +do_idea_decrypt( IDEA_context *c, byte *outbuf, const byte *inbuf ) 3.254 +{ 3.255 + if( !c->have_dk ) { 3.256 + c->have_dk = 1; 3.257 + invert_key( c->ek, c->dk ); 3.258 + } 3.259 + cipher( outbuf, inbuf, c->dk ); 3.260 +} 3.261 + 3.262 +static void 3.263 +idea_decrypt (void *context, byte *out, const byte *in) 3.264 +{ 3.265 + IDEA_context *ctx = context; 3.266 + 3.267 + do_idea_decrypt (ctx, out, in); 3.268 + _gcry_burn_stack (24+3*sizeof (void*)); 3.269 +} 3.270 + 3.271 +gcry_cipher_spec_t _gcry_cipher_spec_idea = 3.272 +{ 3.273 + "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128, sizeof (IDEA_context), 3.274 + idea_setkey, idea_encrypt, idea_decrypt, 3.275 +};
4.1 --- a/gnupg/gnupg.patch Wed Feb 18 16:40:58 2009 +0100 4.2 +++ b/gnupg/gnupg.patch Sat Feb 21 16:39:01 2009 +0100 4.3 @@ -33,3 +33,18 @@ 4.4 cat >conftest.$ac_ext <<_ACEOF 4.5 /* confdefs.h. */ 4.6 _ACEOF 4.7 +Index: configure 4.8 +--- g10/seckey-cert.c.orig 2008-03-18 17:46:32.000000000 +0100 4.9 ++++ g10/seckey-cert.c 2009-02-18 21:25:25.508715635 +0100 4.10 +@@ -209,6 +209,11 @@ 4.11 + csum += checksum (buffer, ndata); 4.12 + gcry_mpi_release (sk->skey[i]); 4.13 + 4.14 ++ if (sk->protect.algo==CIPHER_ALGO_IDEA) { 4.15 ++ buffer[0] = 0; 4.16 ++ buffer[1] = 0; 4.17 ++ } 4.18 ++ 4.19 + err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP, 4.20 + buffer, ndata, &ndata ); 4.21 + xfree (buffer);
5.1 --- a/gnupg/gnupg.spec Wed Feb 18 16:40:58 2009 +0100 5.2 +++ b/gnupg/gnupg.spec Sat Feb 21 16:39:01 2009 +0100 5.3 @@ -37,10 +37,10 @@ 5.4 # package options 5.5 %option with_curl yes 5.6 %option with_ldap no 5.7 +%option with_idea no 5.8 5.9 # list of sources 5.10 Source0: ftp://ftp.gnupg.org/gcrypt/gnupg/gnupg-%{version}.tar.bz2 5.11 -Source1: ftp://ftp.gnupg.dk/pub/contrib-dk/idea.c.gz 5.12 Patch0: gnupg.patch 5.13 5.14 # build information 5.15 @@ -60,6 +60,10 @@ 5.16 BuildPreReq: openldap, openssl 5.17 PreReq: openldap, openssl 5.18 %endif 5.19 +%if "%{with_idea}" == "yes" 5.20 +BuildPreReq: gcrypt::with_idea 5.21 +PreReq: gcrypt::with_idea 5.22 +%endif 5.23 AutoReq: no 5.24 AutoReqProv: no 5.25 5.26 @@ -107,6 +111,9 @@ 5.27 export CC="%{l_cc}" 5.28 export CFLAGS="%{l_cflags -O}" 5.29 export CPPFLAGS="%{l_cppflags}" 5.30 +%if "%{with_idea}" == "yes" 5.31 + export CPPFLAGS="-DUSE_IDEA $CPPFLAGS" 5.32 +%endif 5.33 export LDFLAGS="%{l_ldflags}" 5.34 ./configure \ 5.35 --prefix=%{l_prefix} \