Patch gnupg and its dependency gcrypt to accept use of the IDEA cipher.

Sat, 21 Feb 2009 16:39:01 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 21 Feb 2009 16:39:01 +0100
changeset 107
2f8ffdf7658b
parent 106
5e7005042079
child 108
79a5b329670a

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} \

mercurial