Silk Road forums

Discussion => Security => Topic started by: LouisCyphre on September 15, 2012, 02:43 am

Title: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 15, 2012, 02:43 am
Hello,

Today I am going to show how to modify GPG 1.4.12 and compile it on *nix systems (Linux, BSD, OS X, etc.).  First, though, some important disclaimers:

* This is NOT recommended by Werner Koch, the creator of GPG.

* Use of keys larger than 4096-bit is NOT recommended by anyone in the GPG development and general use community because larger keys may not work with all people, devices or OpenPGP implementations.

* There is a noticable CPU performance hit when creating and using 8192-bit keys or larger.

* The future of OpenPGP is to switch to ECC from RSA and Elgamal in the coming years to provide comparable cryptographic strength to symmetric ciphers with smaller keys.

* If you are new to GPG or Linux/BSD/UNIX then you SHOULD NOT do this until you understand what it is actually doing.

If you still want to create keys that are larger than the current 4096-bit maximum, then this is how you do it.  These instructions assume you are using a *nix system on which you have root access.  The instructions will include compiling in support for the old IDEA cipher, for backwards compatibility with data encrypted during the 1990s.

This tutorial assumes you are familiar with a UNIX shell (e.g. bash) and use of a real text editor (e.g. Emacs or Vim).

Code: [Select]
cd /tmp/
wget -t 0 -c ftp://ftp.gnupg.org/gcrypt/gnupg/gnupg-1.4.12.tar.bz2
wget -t 0 -c ftp://ftp.gnupg.dk/contrib-dk/idea.c.gz
gunzip idea.c.gz
su -

At this point you will be prompted for the root password.  Enter it.  Alternatively you can use:

Code: [Select]
sudo bash
Using sudo to get a bash prompt may be preferable on Ubuntu and OS X systems which do not enable root access by default.

Be EXTREMELY careful from this point on because root access enables you to do anything on your system (unless you're using SELinux or similar mandatory access controls).

Code: [Select]
cd /usr/local/src
cp /tmp/gnupg-1.4.12.tar.bz2 .
tar -xjvf gnupg-1.4.12.tar.bz2
cd gnupg-1.4.12/
cd cipher/
cp /tmp/idea.c .
rm -f idea-stub.c
cd ../g10/

At this point you will need to open a file with your preferred text editor, e.g. Vim or Emacs.

Code: [Select]
vim keygen.c
Code: [Select]
emacs keygen.c
In the text editor skip down to line number 1,580 (you can also search for "4096" to reach the same point).

Replace this line:

Code: [Select]
  unsigned nbits, min, def=2048, max=4096;

With this:

Code: [Select]
  unsigned nbits, min, def=2048, max=16384;

Then save the file and return to the parent directory.

Code: [Select]
cd ..
Then just configure, make and make install.  By default it will install to /usr/local/ directories.  If you already have a version of GPG in there that you don't want to mess with then you should select another prefix and eprefix (e.g. --prefix=/opt/local --eprefix=/opt/local).

Code: [Select]
./configure --enable-idea --enable-camellia
make
make install

That's it, you should now exit out of root or superuser access.

You will now have a /usr/local/bin/gpg executable which is capable of creating 16384-bit keys.

You should make sure your gpg.conf is configured as per the instructions here:

http://dkn255hz262ypmii.onion/index.php?topic=34204.0

Then use expert mode to create a new key as described here:

http://dkn255hz262ypmii.onion/index.php?topic=28474.0

When you are prompted to select your key size, you will be able to enter any value up to and including 16,384 bits.

Most systems will not have any trouble creating keys with 8,192 bits of strength, but some will have real trouble creating keys larger than that.  Usually they will complain that they have run out of secure memory when that occurs.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 15, 2012, 08:30 am
Couple of minor nit-picks:

First off, the site with the idea.c source code appears to be down. Not sure if this is temporary, or by design.

I must admit, I didn't check it because I last did all this shortly after 1.4.12 was released and I didn't feel like recompiling just for the guide.

Second, in addition to the idea.c.gz package, you should also have reminded the user to download/verify the PGP detached signature:

Yep, my bad.

Did you manage to find a copy or did you already have it?  If it's still not accessible I can post it.

Third, it does not appear to be necessary to use the --enable-idea and --enable-camellia switches.  Compiling in the usual manner without these switches (at least in my case) nevertheless shows both IDEA and Camellia enabled:

Using --enable-idea is probably unnecessary, but --help still shows that --camellia should be explicitly enabled.  That does seem to vary with the versions for some distributions.  It's also possible that Camellia is now enabled by default, but the configure help info has not been updated to reflect that.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 15, 2012, 08:38 am
of course you should make sure to torify wget before doing this
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 15, 2012, 08:43 am
I don't see why you ask users to wget idea.c considering that has to do with symmetric encryption and I can not in the slightest think of why users would need to do anything with that to change the maximum asymmetric key strength. However if users wget that file without torifying wget they will leak their real IP address when they wget both gnupg-1.4.12.tar.bz2 and idea.c.gz, and I imagine that will be a pretty small crowd of people considering I doubt that barely anyone downloads that combination of files in such a way.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 15, 2012, 08:46 am
of course you should make sure to torify wget before doing this

Good point.  For everyone else, fire up the Vidalia Bundle and then add these lines to ~/.wgetrc:

https_proxy = http://127.0.0.1:8118/
http_proxy = http://127.0.0.1:8118/
ftp_proxy = http://127.0.0.1:8118/

Although personally I cheat and have a couple of shell scripts, one has:

Code: [Select]
#!/bin/sh

exec /usr/local/bin/wget --execute=http_proxy=127.0.0.1:8118 -t 0 -c "$@"

And the other has:

Code: [Select]
#!/bin/sh

exec /usr/local/bin/wget --execute=http_proxy=127.0.0.1:8118 --no-check-certificate -t 0 -c "$@"

Make sure the path for wget is correct for your system before using the above.

Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 15, 2012, 08:50 am
Okay problem solved :)
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 15, 2012, 08:50 am
I don't see why you ask users to wget idea.c considering that has to do with symmetric encryption and I can not in the slightest think of why users would need to do anything with that to change the maximum asymmetric key strength. However if users wget that file without torifying wget they will leak their real IP address when they wget both gnupg-1.4.12.tar.bz2 and idea.c.gz, and I imagine that will be a pretty small crowd of people considering I doubt that barely anyone downloads that combination of files in such a way.

Old habits.  IDEA is pretty optional and there probably aren't many people here who have to worry about decrypting old files that were encrypted before it was removed.

It may give some idea how long I've been doing this.  Like Guru, I remember the Crypto Wars and I'm convinced that they've restarted (or that the "official" announcement that they ended may have been premature).
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 15, 2012, 08:56 am
In case there is trouble with the FTP server with the IDEA cipher and people do want to include it, here's the copy I've obtained previously.

idea.c:
Code: [Select]
/* idea.c  -  IDEA algorithm
 * Copyright (c) 1997, 1998, 1999, 2001, 2002 by Werner Koch (dd9jn)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Werner Koch shall not be
 * used in advertising or otherwise to promote the sale, use or other dealings
 * in this Software without prior written authorization from Werner Koch.
 *
 * DUE TO PATENT CLAIMS THE DISTRIBUTION OF THE SOFTWARE IS NOT ALLOWED IN
 * THESE COUNTRIES:
 *     AUSTRIA, FRANCE, GERMANY, ITALY, JAPAN, THE NETHERLANDS,
 *     SPAIN, SWEDEN, SWITZERLAND, THE UK AND THE US.
 */

/*
 * Please see http://www.noepatents.org/ to learn why software patents
 * are bad for society and what you can do to fight them.
 *
 * The code herein is based on the one from:
 *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
 *    ISBN 0-471-11709-9. .
 *
 * To build a GnuPG with IDEA support, copy this file into the cipher/
 * directory of the gnupg distribution, and ./configure and make as
 * usual.  IDEA will be built directly in to the GnuPG binary.  This
 * is the recommended way to use this file.
 *
 * If you are not building IDEA directly into GnuPG, and need to build
 * the dynamically loadable IDEA module, compile with:
       gcc -Wall -O2 -shared -fPIC -o idea idea.c
 *
 * If you building the dynamically loadable IDEA module on a bigendian
 * platform (Sparc, PowerPC, etc.) and the endian detection does not
 * work properly for whatever reason, you will get an error like "idea
 * encryption (0) failed" when you use GnuPG.  In that case, compile
 * with:
       gcc -Wall -O2 -shared -fPIC -DBIG_ENDIAN_HOST -o idea idea.c
 *
 * How to build a Windows DLL using mingw32/cpd (see gnupg/doc/README.W32):
       echo EXPORTS >temp.def ; \
       echo "    idea_get_info" >>temp.def ; \
       mingw32 gcc -c idea.c ; \
       mingw32 dlltool -e temp.o  --as `mingw32 --get-path as` \
               --def temp.def  idea.o ; \
       mingw32 gcc -mdll -Wl,--base-file -Wl,temp.base \
               -o idea.dll temp.o idea.o ; \
       mingw32 dlltool -e temp.o  --as `mingw32 --get-path as` \
               --def temp.def --base-file temp.base idea.o ; \
       mingw32 gcc -mdll -o idea.dll temp.o idea.o ; \
       mingw32 strip idea.dll
 *
 * 2001-06-08 wk  Changed distribution conditions
 * 2001-06-11 wk  Fixed invert_key (which is not used in CFB mode)
 *                Thanks to Mark A. Borgerding.  Added definition for
 *                the PowerPC.
 * 2002-08-03 wk  Removed dependeny to g10_log_fatal and perform selftest
 *                in idea_get_info.
 * 2002-08-07 wk  Removed unused macros and types etc.
 * 2002-09-13 wk  Explained how to build a Windows DLL.
 * 2002-09-20 wk  Made the DLL relocatable
 * 2002-12-11 wk  __ppc__ is used on Darwin instead of __powerpc__.
 * 2003-02-15 dshaw Try and get endianness from config.h.  Accept
 *                  __sparc and _POWER.
 */

#ifdef HAVE_CONFIG_H
/* If we're building as part of GnuPG, we can get endianness from
   config.h */
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#if !defined(BIG_ENDIAN_HOST) && !defined(LITTLE_ENDIAN_HOST)
/* Try to handle endianness if we didn't get it from config.h */
#if defined(__mc68000__) || defined (__sparc__) || defined (__sparc) \
    || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__)) ) \
    || defined (__PPC__) || defined(__powerpc__) || defined(__ppc__) \
    || defined (_POWER) \
    || defined(__hpux__) /* should be replaced by the Macro for the PA */
  #define BIG_ENDIAN_HOST 1
#else
  #define LITTLE_ENDIAN_HOST 1
#endif
#endif

typedef unsigned short u16; /* Note: Make sure this is a 16 bit type. */
typedef unsigned long  u32; /* Note: Make sure this is a 32 bit type. */

/* end configurable stuff */


#ifndef DIM
  #define DIM(v) (sizeof(v)/sizeof((v)[0]))
#endif


/* local stuff */

#define FNCCAST_SETKEY(f)   ((int(*)(void*, unsigned char*, unsigned int))(f))
#define FNCCAST_CRYPT(f) ((void(*)(void*, unsigned char*, unsigned char*))(f))

#define IDEA_KEYSIZE 16
#define IDEA_BLOCKSIZE 8
#define IDEA_ROUNDS 8
#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)

typedef struct {
    u16 ek[IDEA_KEYLEN];
    u16 dk[IDEA_KEYLEN];
    int have_dk;
} IDEA_context;


static int do_setkey( IDEA_context *c, unsigned char *key, unsigned keylen );
static void encrypt_block( IDEA_context *bc, unsigned char *outbuf,
                           unsigned char *inbuf );
static void decrypt_block( IDEA_context *bc, unsigned char *outbuf,
                           unsigned char *inbuf );
static int selftest(int);



static u16
mul_inv( u16 x )
{
    u16 t0, t1;
    u16 q, y;

    if( x < 2 )
return x;
    t1 = 0x10001L / x;
    y =  0x10001L % x;
    if( y == 1 )
return (1-t1) & 0xffff;

    t0 = 1;
    do {
q = x / y;
x = x % y;
t0 += q * t1;
if( x == 1 )
    return t0;
q = y / x;
y = y % x;
t1 += q * t0;
    } while( y != 1 );
    return (1-t1) & 0xffff;
}



static void
expand_key( unsigned char *userkey, u16 *ek )
{
    int i,j;

    for(j=0; j < 8; j++ ) {
ek[j] = (*userkey << 8) + userkey[1];
userkey += 2;
    }
    for(i=0; j < IDEA_KEYLEN; j++ ) {
i++;
ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
ek += i & 8;
i &= 7;
    }
}


static void
invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
{
    int i;
    u16 t1, t2, t3;
    u16 temp[IDEA_KEYLEN];
    u16 *p = temp + IDEA_KEYLEN;

    t1 = mul_inv( *ek++ );
    t2 = -*ek++;
    t3 = -*ek++;
    *--p = mul_inv( *ek++ );
    *--p = t3;
    *--p = t2;
    *--p = t1;

    for(i=0; i < IDEA_ROUNDS-1; i++ ) {
t1 = *ek++;
*--p = *ek++;
*--p = t1;

t1 = mul_inv( *ek++ );
t2 = -*ek++;
t3 = -*ek++;
*--p = mul_inv( *ek++ );
*--p = t2;
*--p = t3;
*--p = t1;
    }
    t1 = *ek++;
    *--p = *ek++;
    *--p = t1;

    t1 = mul_inv( *ek++ );
    t2 = -*ek++;
    t3 = -*ek++;
    *--p = mul_inv( *ek++ );
    *--p = t3;
    *--p = t2;
    *--p = t1;
    memcpy(dk, temp, sizeof(temp) );
    memset(temp, 0, sizeof(temp) );  /* burn temp */
}


static void
cipher( unsigned char *outbuf, unsigned char *inbuf, u16 *key )
{
    u16 x1, x2, x3,x4, s2, s3;
    u16 *in, *out;
    int r = IDEA_ROUNDS;
#define MUL(x,y) \
do {u16 _t16; u32 _t32;     \
    if( (_t16 = (y)) ) {     \
if( (x = (x)&0xffff) ) {     \
    _t32 = (u32)x * _t16;     \
    x = _t32 & 0xffff;     \
    _t16 = _t32 >> 16;     \
    x = ((x)-_t16) + (x<_t16?1:0);  \
}     \
else {     \
    x = 1 - _t16;     \
}     \
    }     \
    else {     \
x = 1 - x;     \
    }     \
} while(0)

    in = (u16*)inbuf;
    x1 = *in++;
    x2 = *in++;
    x3 = *in++;
    x4 = *in;
#ifdef LITTLE_ENDIAN_HOST
    x1 = (x1>>8) | (x1<<8);
    x2 = (x2>>8) | (x2<<8);
    x3 = (x3>>8) | (x3<<8);
    x4 = (x4>>8) | (x4<<8);
#endif
    do {
MUL(x1, *key++);
x2 += *key++;
x3 += *key++;
MUL(x4, *key++ );

s3 = x3;
x3 ^= x1;
MUL(x3, *key++);
s2 = x2;
x2 ^=x4;
x2 += x3;
MUL(x2, *key++);
x3 += x2;

x1 ^= x2;
x4 ^= x3;

x2 ^= s3;
x3 ^= s2;
    } while( --r );
    MUL(x1, *key++);
    x3 += *key++;
    x2 += *key++;
    MUL(x4, *key);

    out = (u16*)outbuf;
  #ifdef LITTLE_ENDIAN_HOST
    *out++ = (x1>>8) | (x1<<8);
    *out++ = (x3>>8) | (x3<<8);
    *out++ = (x2>>8) | (x2<<8);
    *out   = (x4>>8) | (x4<<8);
  #else
    *out++ = x1;
    *out++ = x3;
    *out++ = x2;
    *out   = x4;
  #endif
  #undef MUL
}


static int
do_setkey( IDEA_context *c, unsigned char *key, unsigned keylen )
{
    assert(keylen == 16);
    c->have_dk = 0;
    expand_key( key, c->ek );
    invert_key( c->ek, c->dk );
    return 0;
}

static void
encrypt_block( IDEA_context *c, unsigned char *outbuf, unsigned char *inbuf )
{
    cipher( outbuf, inbuf, c->ek );
}

static void
decrypt_block( IDEA_context *c, unsigned char *outbuf, unsigned char *inbuf )
{
    if( !c->have_dk ) {
       c->have_dk = 1;
       invert_key( c->ek, c->dk );
    }
    cipher( outbuf, inbuf, c->dk );
}


static int
selftest( int check_decrypt )
{
static struct {
    unsigned char key[16];
    unsigned char plain[8];
    unsigned char cipher[8];
} test_vectors[] = {
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 },
      { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } },
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
      { 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } },
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF },
      { 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } },
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 },
      { 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } },
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E },
      { 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } },
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 },
      { 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } },
    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
      { 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 },
      { 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } },
    { { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14,
0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 },
      { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
      { 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } },
    { { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3,
0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 },
      { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
      { 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } },
    { { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 },
      { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA },
      { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } },
    { { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A,
0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 },
      { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 },
      { 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } }
};
    IDEA_context c;
    unsigned char buffer[8];
    int i;

    for(i=0; i < DIM(test_vectors); i++ ) {
do_setkey( &c, test_vectors[i].key, 16 );
if( !check_decrypt ) {
    encrypt_block( &c, buffer, test_vectors[i].plain );
    if( memcmp( buffer, test_vectors[i].cipher, 8 ) )
              {
fprintf (stderr, "idea encryption (%d) failed\n", i);
                return -1;
              }
}
else {
    decrypt_block( &c, buffer, test_vectors[i].cipher );
    if( memcmp( buffer, test_vectors[i].plain, 8 ) )
              {
fprintf (stderr, "idea decryption (%d) failed\n", i);
                return -1;
              }
}
    }
    return 0;
}


/****************
 * Return some information about the algorithm.  We need algo here to
 * distinguish different flavors of the algorithm.
 * Returns: A pointer to string describing the algorithm or NULL if
 *     the ALGO is invalid.
 */
const char *
idea_get_info( int algo, size_t *keylen,
               size_t *blocksize, size_t *contextsize,
               int (**r_setkey)( void *c, unsigned char *key,
                                      unsigned keylen ),
               void (**r_encrypt)( void *c, unsigned char *outbuf,
                                   unsigned char *inbuf ),
               void (**r_decrypt)( void *c, unsigned char *outbuf,
                                   unsigned char *inbuf )
               )
{
    static int initialized = 0;

    if( !initialized ) {
initialized = 1;
if ( selftest(0) || selftest(1) )
          return NULL;
    }
    *keylen = 128;
    *blocksize = 8;
    *contextsize = sizeof(IDEA_context);
    *r_setkey = FNCCAST_SETKEY(do_setkey);
    *r_encrypt= FNCCAST_CRYPT(encrypt_block);
    *r_decrypt= FNCCAST_CRYPT(decrypt_block);
    if( algo == 1 )
return "IDEA";
    return NULL;
}



const char * const gnupgext_version = "IDEA ($Revision: 1.11 $)";

static struct {
    int class;
    int version;
    int  value;
    void (*func)(void);
} func_table[] = {
    { 20, 1, 0, (void(*)(void))idea_get_info },
    { 21, 1, 1 },
};



/****************
 * Enumerate the names of the functions together with informations about
 * this function. Set sequence to an integer with a initial value of 0 and
 * do not change it.
 * If what is 0 all kind of functions are returned.
 * Return values: class := class of function:
 *    10 = message digest algorithm info function
 *    11 = integer with available md algorithms
 *    20 = cipher algorithm info function
 *    21 = integer with available cipher algorithms
 *    30 = public key algorithm info function
 *    31 = integer with available pubkey algorithms
 *   version = interface version of the function/pointer
 *     (currently this is 1 for all functions)
 */
void *
gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
{
    void *ret;
    int i = *sequence;

    do {
if( i >= DIM(func_table) || i < 0 ) {
    return NULL;
}
*class = func_table[i].class;
*vers  = func_table[i].version;
switch( *class ) {
  case 11:
  case 21:
  case 31:
    ret = &func_table[i].value;
    break;
  default:
    ret = (void*)func_table[i].func;
    break;
}
i++;
    } while( what && what != *class );

    *sequence = i;
    return ret;
}
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 15, 2012, 10:29 am
Second, in addition to the idea.c.gz package, you should also have reminded the user to download/verify the PGP detached signature:

Yep, my bad.

Did you manage to find a copy or did you already have it?  If it's still not accessible I can post it.

I already had a copy of Werner's idea.c.gz stashed.  I also have a copy of Disastry's idea.c source as well.

Would it be worth posting that or was it only used with old versions of PGP(i)?

Disastry (Janis Jagars) will be gone 10 years at the end of October -- it seems like yesterday that I read his obituary.  He was as  talented as all get out -- he updated the DOS versions of PGP to include the SHA-1, Tiger and Whirlpool hash algorithms, as well as adding DH/DSS capability to it.

That name sounds very familiar, probably from mailing lists.

He also cleaned-up the Mixmaster code, I believe with Len Sassaman.  Sassaman died earlier this year.  (Gawd, I feel old!)

Yeah, that one was a Hell of a shock, especially given the circumstances.  :(

I suspect that the help just hasn't been updated. Camellia has been in there for some time; I've been compiling my own, and I've never used the --enable-camellia switch, and it's been there nevertheless.

You're probably right.  That's certainly the sort of thing that could be easily overlooked, especially with the focus being on 2.0.x and wanting to move from both branches to 2.1.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: Shannon on September 15, 2012, 07:42 pm
secmem can be ramped up by changing "got_secmem=secmem_init( 32768 );" to "got_secmem=secmem_init( 524288 );" in g10/gpg.c
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 18, 2012, 03:14 am
secmem can be ramped up by changing "got_secmem=secmem_init( 32768 );" to "got_secmem=secmem_init( 524288 );" in g10/gpg.c

Very nice!  That one's going into the archives, thanks!  :)
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: Shannon on September 18, 2012, 03:27 am
i imagine that once you let gpg get greedy with the secmem the limiting factor will be your entropy pool

/dev/random is better than /dev/urandom but it's slow and werner says that even /dev/random might not provide enough entropy estimation. oh well :( i guess you can make it faster by piping your ethernet card into rndcontrol and downloading a bunch of porn or by doing something hackish like "rngd –r /dev/urandom;find /usr /var /tmp /opt -type f -print0 | xargs -0 cat > /dev/null"
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 18, 2012, 03:40 am
i imagine that once you let gpg get greedy with the secmem the limiting factor will be your entropy pool

/dev/random is better than /dev/urandom but it's slow and werner says that even /dev/random might not provide enough entropy estimation. oh well :( i guess you can make it faster by piping your ethernet card into rndcontrol and downloading a bunch of porn or by doing something hackish like "rngd –r /dev/urandom;find /usr /var /tmp /opt -type f -print0 | xargs -0 cat > /dev/null"

Once you have to start worrying about whether or not the entropy pool is solid enough during each key generation then you really have to question whether or not there is any practical value in generating asymmetric keys larger than 4K or even 8K.

The reality is that if a 4K key isn't enough for whatever you're doing then you're in much deeper shit than this place is ever likely to attract and the vectors of attack used against you will be very different than simply attempting to crack your messages.

Still, people wanted to know how to do this and it didn't take long to write.  ;)
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 18, 2012, 09:28 am
At the end of the day fucking with the source code of GPG or trying hackish ways of seeding /dev/urandom are far more likely to fuck you than you are to be fucked by using a 4,096 bit RSA key.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 18, 2012, 09:30 am
/dev/urandom should be more than good enough, I believe that /dev/random attempts to accumulate true randomness and /dev/urandom is pseudo-randomness that is seeded from /dev/random, if an attacker doesn't know the seed provided from /dev/random they should not be able to determine the output of /dev/urandom
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 18, 2012, 09:37 am
Just looked it up, /dev/random produces output only if there is sufficient entropy in the entropy pool, /dev/urandom doesn't block (unblock random) if there is not sufficient entropy and keeps producing output. It is unlikely that a freshly seeded /dev/urandom will be pwnable but it is theoretically weak to certain attacks if there is not sufficient entropy, /dev/random on the other hand is not weak to these theoretical attacks because it blocks until there is sufficient entropy.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 18, 2012, 10:18 am
At the end of the day fucking with the source code of GPG or trying hackish ways of seeding /dev/urandom are far more likely to fuck you than you are to be fucked by using a 4,096 bit RSA key.

No arguments here.  Seriously, 4096-bit RSA or Elgamal is plenty good enough for almost everyone up to something dodgy and certainly everyone here.  By the time we actually need to worry about something stronger than 4K keys we'll all be using ECC keys anyway.

Still, Pine said she wanted to generate an 8K key because it looks cool, so here's the guide.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: Shannon on September 18, 2012, 06:03 pm
/dev/urandom should be more than good enough

dd9jn, the lead developer of gpg disagrees with this, his opinion is that urandom is certainly not good enough and random is probably not good enough, i don't know why he thinks this though and will have to ask him next time i see him online

i agree with the both of you though that you don't need to worry about the quality of your entropy pool unless your name is saddam bin laden muhammad ali jihad, i was mainly worried about the speed of the pool since i'm an impatient fuck
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: kmfkewm on September 20, 2012, 07:46 am
/dev/urandom should be more than good enough

dd9jn, the lead developer of gpg disagrees with this, his opinion is that urandom is certainly not good enough and random is probably not good enough, i don't know why he thinks this though and will have to ask him next time i see him online

i agree with the both of you though that you don't need to worry about the quality of your entropy pool unless your name is saddam bin laden muhammad ali jihad, i was mainly worried about the speed of the pool since i'm an impatient fuck

Well if /dev/random isn't good enough then /dev/urandom can't possibly be.
Title: Re: GPG HOWTO: Compiling GPG 1.4.x to Support Larger Key Creation (advanced)
Post by: LouisCyphre on September 20, 2012, 11:03 am
/dev/urandom should be more than good enough

dd9jn, the lead developer of gpg disagrees with this, his opinion is that urandom is certainly not good enough and random is probably not good enough, i don't know why he thinks this though and will have to ask him next time i see him online

i agree with the both of you though that you don't need to worry about the quality of your entropy pool unless your name is saddam bin laden muhammad ali jihad, i was mainly worried about the speed of the pool since i'm an impatient fuck

Well if /dev/random isn't good enough then /dev/urandom can't possibly be.

Don't forget that the behaviour of /dev/random and /dev/urandon (as well as other [P]RNGs like /dev/arandom and EGD) vary according to operating system.  So far you've both been discussing the Linux specific variation between /dev/random and /dev/urandom.

https://en.wikipedia.org/wiki//dev/random