mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
See ChangeLog: Sat Nov 13 17:44:23 CET 1999 Werner Koch
This commit is contained in:
parent
a10fe4efb0
commit
881e513237
57 changed files with 1067 additions and 631 deletions
|
@ -1,3 +1,46 @@
|
|||
Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* pubkey.c (disable_pubkey_algo): Made static.
|
||||
(gcry_pk_ctl): New.
|
||||
|
||||
* random.c (get_random_bits): Renamed to ...
|
||||
(get_random_bytes): ... this and made static.
|
||||
(gcry_random_bytes): New.
|
||||
(gcry_random_bytes_secure): New.
|
||||
(randomize_buffer): Renamed to ...
|
||||
(gcry_randomize): ...this.
|
||||
|
||||
* md.c (gcry_md_hash_buffer): New.
|
||||
|
||||
* pubkey.c (gcry_pk_algo_info): 4 new commands.
|
||||
(pubkey_get_npkey): Made static.
|
||||
(pubkey_get_nskey): Made static.
|
||||
(pubkey_get_nsig): Made static.
|
||||
(pubkey_get_nenc): Made static.
|
||||
|
||||
* pubkey.c: Removed all G10ERR_xxx.
|
||||
* cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
|
||||
* md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
|
||||
* cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
|
||||
* blowfish.c: Ditto.
|
||||
* des.c: Ditto.
|
||||
* twofish.c: Ditto.
|
||||
* dsa.c: Ditto.
|
||||
* elgamal.c: Ditto.
|
||||
|
||||
* g10c.c: Removed
|
||||
|
||||
* cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
|
||||
if we are out of core.
|
||||
* dynload.c: Replaced all memory allocation functions.
|
||||
* md.c: Ditto.
|
||||
* primegen.c: Ditto.
|
||||
* pubkey.c: Ditto.
|
||||
* random.c: Ditto.
|
||||
* rndw32.c: Ditto.
|
||||
* elgamal.c: Ditto.
|
||||
* dsa.c: Ditto.
|
||||
|
||||
Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
|
||||
|
||||
* elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
|
||||
|
|
|
@ -57,7 +57,6 @@ libcipher_la_SOURCES = cipher.c \
|
|||
rmd.h \
|
||||
dsa.h \
|
||||
dsa.c \
|
||||
g10c.c \
|
||||
smallprime.c \
|
||||
construct.c
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "types.h"
|
||||
#include "errors.h"
|
||||
#include "g10lib.h"
|
||||
#include "blowfish.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
@ -498,7 +498,7 @@ bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
|
|||
fprintf(stderr,"%s\n", selftest_failed );
|
||||
}
|
||||
if( selftest_failed )
|
||||
return G10ERR_SELFTEST_FAILED;
|
||||
return GCRYERR_SELFTEST;
|
||||
|
||||
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
|
||||
c->p[i] = ps[i];
|
||||
|
@ -559,7 +559,7 @@ bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
|
|||
for( j=i+1; j < 256; j++) {
|
||||
if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
|
||||
(c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
|
||||
return G10ERR_WEAK_KEY;
|
||||
return GCRYERR_WEAK_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "g10lib.h"
|
||||
#include "types.h"
|
||||
#include "errors.h"
|
||||
#include "cast5.h"
|
||||
|
||||
|
||||
|
@ -566,10 +566,10 @@ cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
|
|||
fprintf(stderr,"CAST5 selftest failed (%s).\n", selftest_failed );
|
||||
}
|
||||
if( selftest_failed )
|
||||
return G10ERR_SELFTEST_FAILED;
|
||||
return GCRYERR_SELFTEST;
|
||||
|
||||
if( keylen != 16 )
|
||||
return G10ERR_WRONG_KEYLEN;
|
||||
return GCRYERR_INV_KEYLEN;
|
||||
|
||||
x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
|
||||
x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7];
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "errors.h"
|
||||
#include "cipher.h"
|
||||
#include "des.h"
|
||||
#include "blowfish.h"
|
||||
|
@ -289,12 +288,12 @@ check_cipher_algo( int algo )
|
|||
if( cipher_table[i].algo == algo ) {
|
||||
for(i=0; i < DIM(disabled_algos); i++ ) {
|
||||
if( disabled_algos[i] == algo )
|
||||
return G10ERR_CIPHER_ALGO;
|
||||
return GCRYERR_INV_CIPHER_ALGO;
|
||||
}
|
||||
return 0; /* okay */
|
||||
}
|
||||
} while( load_cipher_modules() );
|
||||
return G10ERR_CIPHER_ALGO;
|
||||
return GCRYERR_INV_CIPHER_ALGO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -356,13 +355,13 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
|
|||
|
||||
/* check whether the algo is available */
|
||||
if( check_cipher_algo( algo ) ) {
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check flags */
|
||||
if( (flags & ~(GCRY_CIPHER_SECURE|GCRY_CIPHER_ENABLE_SYNC)) ) {
|
||||
set_lasterr( GCRYERR_INV_ARG );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -386,17 +385,21 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
|
|||
/* FIXME: issue a warning when this mode is used */
|
||||
break;
|
||||
default:
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ? perform selftest here and mark this with a flag in cipher_table ? */
|
||||
|
||||
h = secure ? m_alloc_secure_clear( sizeof *h
|
||||
h = secure ? g10_calloc_secure( 1, sizeof *h
|
||||
+ cipher_table[idx].contextsize
|
||||
- sizeof(PROPERLY_ALIGNED_TYPE) )
|
||||
: m_alloc_clear( sizeof *h + cipher_table[idx].contextsize
|
||||
: g10_calloc( 1, sizeof *h + cipher_table[idx].contextsize
|
||||
- sizeof(PROPERLY_ALIGNED_TYPE) );
|
||||
if( !h ) {
|
||||
set_lasterr( GCRYERR_NO_MEM );
|
||||
return NULL;
|
||||
}
|
||||
h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
|
||||
h->algo = algo;
|
||||
h->mode = mode;
|
||||
|
@ -420,7 +423,7 @@ gcry_cipher_close( GCRY_CIPHER_HD h )
|
|||
return;
|
||||
}
|
||||
h->magic = 0;
|
||||
m_free(h);
|
||||
g10_free(h);
|
||||
}
|
||||
|
||||
|
||||
|
@ -449,7 +452,7 @@ cipher_setiv( GCRY_CIPHER_HD c, const byte *iv, unsigned ivlen )
|
|||
|
||||
|
||||
static void
|
||||
do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
||||
do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
|
@ -461,7 +464,7 @@ do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
|||
}
|
||||
|
||||
static void
|
||||
do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
||||
do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
|
@ -473,7 +476,7 @@ do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
|||
}
|
||||
|
||||
static void
|
||||
do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
||||
do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
|
||||
{
|
||||
unsigned int n;
|
||||
byte *ivp;
|
||||
|
@ -494,7 +497,7 @@ do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
|||
}
|
||||
|
||||
static void
|
||||
do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
||||
do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks )
|
||||
{
|
||||
unsigned int n;
|
||||
byte *ivp;
|
||||
|
@ -517,7 +520,7 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks )
|
|||
|
||||
|
||||
static void
|
||||
do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes )
|
||||
do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes )
|
||||
{
|
||||
byte *ivp;
|
||||
size_t blocksize = c->blocksize;
|
||||
|
@ -561,7 +564,7 @@ do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes )
|
|||
}
|
||||
|
||||
static void
|
||||
do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes )
|
||||
do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes )
|
||||
{
|
||||
byte *ivp;
|
||||
ulong temp;
|
||||
|
@ -624,7 +627,8 @@ do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes )
|
|||
* Depending on the mode some some contraints apply to NBYTES.
|
||||
*/
|
||||
static void
|
||||
cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes )
|
||||
cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
|
||||
const byte *inbuf, unsigned nbytes )
|
||||
{
|
||||
switch( c->mode ) {
|
||||
case GCRY_CIPHER_MODE_ECB:
|
||||
|
@ -680,7 +684,8 @@ gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
|
|||
* Depending on the mode some some contraints apply to NBYTES.
|
||||
*/
|
||||
static void
|
||||
cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes )
|
||||
cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
|
||||
unsigned nbytes )
|
||||
{
|
||||
switch( c->mode ) {
|
||||
case GCRY_CIPHER_MODE_ECB:
|
||||
|
@ -760,7 +765,7 @@ gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
|
|||
* integer with the algo number.
|
||||
*/
|
||||
if( h || !buffer || buflen != sizeof(int) )
|
||||
return set_lasterr( GCRYERR_INV_ARG );
|
||||
return set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
disable_cipher_algo( *(int*)buffer );
|
||||
break;
|
||||
|
||||
|
@ -819,26 +824,26 @@ gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes)
|
|||
switch( what ) {
|
||||
case GCRYCTL_GET_KEYLEN:
|
||||
if( buffer || nbytes ) {
|
||||
set_lasterr( GCRYERR_INV_ARG );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
break;
|
||||
}
|
||||
ui = cipher_get_keylen( algo );
|
||||
if( ui > 0 && ui <= 512 )
|
||||
return (int)ui/8;
|
||||
/* the only reason is an invalid algo or a strange blocksize */
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
break;
|
||||
|
||||
case GCRYCTL_GET_BLKLEN:
|
||||
if( buffer || nbytes ) {
|
||||
set_lasterr( GCRYERR_INV_ARG );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
break;
|
||||
}
|
||||
ui = cipher_get_blocksize( algo );
|
||||
if( ui > 0 && ui < 10000 )
|
||||
return (int)ui;
|
||||
/* the only reason is an invalid algo or a strange blocksize */
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
break;
|
||||
|
||||
case GCRYCTL_TEST_ALGO:
|
||||
|
@ -847,7 +852,7 @@ gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes)
|
|||
break;
|
||||
}
|
||||
if( check_cipher_algo( algo ) ) {
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
|
10
cipher/des.c
10
cipher/des.c
|
@ -116,7 +116,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h> /* memcpy, memcmp */
|
||||
#include "types.h" /* for byte and u32 typedefs */
|
||||
#include "errors.h"
|
||||
#include "g10lib.h"
|
||||
#include "des.h"
|
||||
|
||||
#if defined(__GNUC__) && defined(__GNU_LIBRARY__)
|
||||
|
@ -558,7 +558,7 @@ des_setkey (struct _des_ctx *ctx, const byte * key)
|
|||
int i;
|
||||
|
||||
if( selftest_failed )
|
||||
return G10ERR_SELFTEST_FAILED;
|
||||
return GCRYERR_SELFTEST;
|
||||
|
||||
des_key_schedule (key, ctx->encrypt_subkeys);
|
||||
|
||||
|
@ -944,14 +944,14 @@ static int
|
|||
do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
|
||||
{
|
||||
if( selftest_failed )
|
||||
return G10ERR_SELFTEST_FAILED;
|
||||
return GCRYERR_SELFTEST;
|
||||
if( keylen != 24 )
|
||||
return G10ERR_WRONG_KEYLEN;
|
||||
return GCRYERR_INV_KEYLEN;
|
||||
|
||||
tripledes_set3keys ( ctx, key, key+8, key+16);
|
||||
|
||||
if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) )
|
||||
return G10ERR_WEAK_KEY;
|
||||
return GCRYERR_WEAK_KEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
31
cipher/dsa.c
31
cipher/dsa.c
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
|
@ -77,7 +78,7 @@ gen_k( MPI q )
|
|||
progress('.');
|
||||
|
||||
if( !rndbuf || nbits < 32 ) {
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
rndbuf = get_random_bits( nbits, 1, 1 );
|
||||
}
|
||||
else { /* change only some of the higher bits */
|
||||
|
@ -86,7 +87,7 @@ gen_k( MPI q )
|
|||
* maybe it is easier to do this directly in random.c */
|
||||
char *pp = get_random_bits( 32, 1, 1 );
|
||||
memcpy( rndbuf,pp, 4 );
|
||||
m_free(pp);
|
||||
g10_free(pp);
|
||||
}
|
||||
mpi_set_buffer( k, rndbuf, nbytes, 0 );
|
||||
if( mpi_test_bit( k, nbits-1 ) )
|
||||
|
@ -108,7 +109,7 @@ gen_k( MPI q )
|
|||
}
|
||||
break; /* okay */
|
||||
}
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
if( DBG_CIPHER )
|
||||
progress('\n');
|
||||
|
||||
|
@ -131,7 +132,7 @@ test_keys( DSA_secret_key *sk, unsigned qbits )
|
|||
/*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
|
||||
{ char *p = get_random_bits( qbits, 0, 0 );
|
||||
mpi_set_buffer( test, p, (qbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
g10_free(p);
|
||||
}
|
||||
|
||||
sign( out1_a, out1_b, test, sk );
|
||||
|
@ -202,12 +203,12 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
|||
else { /* change only some of the higher bits (= 2 bytes)*/
|
||||
char *r = get_random_bits( 16, 2, 1 );
|
||||
memcpy(rndbuf, r, 16/8 );
|
||||
m_free(r);
|
||||
g10_free(r);
|
||||
}
|
||||
mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
|
||||
mpi_clear_highbit( x, qbits+1 );
|
||||
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
mpi_free( e );
|
||||
mpi_free( h );
|
||||
|
||||
|
@ -347,7 +348,7 @@ dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
|
|||
DSA_secret_key sk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
|
||||
generate( &sk, nbits, retfactors );
|
||||
skey[0] = sk.p;
|
||||
|
@ -365,9 +366,9 @@ dsa_check_secret_key( int algo, MPI *skey )
|
|||
DSA_secret_key sk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.q = skey[1];
|
||||
|
@ -375,7 +376,7 @@ dsa_check_secret_key( int algo, MPI *skey )
|
|||
sk.y = skey[3];
|
||||
sk.x = skey[4];
|
||||
if( !check_secret_key( &sk ) )
|
||||
return G10ERR_BAD_SECKEY;
|
||||
return GCRYERR_BAD_SECRET_KEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -388,9 +389,9 @@ dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||
DSA_secret_key sk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.q = skey[1];
|
||||
|
@ -410,17 +411,17 @@ dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
|||
DSA_public_key pk;
|
||||
|
||||
if( algo != PUBKEY_ALGO_DSA )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !data[0] || !data[1] || !hash
|
||||
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
pk.p = pkey[0];
|
||||
pk.q = pkey[1];
|
||||
pk.g = pkey[2];
|
||||
pk.y = pkey[3];
|
||||
if( !verify( data[0], data[1], hash, &pk ) )
|
||||
return G10ERR_BAD_SIGN;
|
||||
return GCRYERR_BAD_SIGNATURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <dl.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "dynload.h"
|
||||
|
@ -131,12 +132,12 @@ register_cipher_extension( const char *mainpgm, const char *fname )
|
|||
tmp = make_filename(fname, NULL);
|
||||
else
|
||||
tmp = make_filename(GNUPG_LIBDIR, fname, NULL);
|
||||
el = m_alloc_clear( sizeof *el + strlen(tmp) );
|
||||
el = g10_xcalloc( 1, sizeof *el + strlen(tmp) );
|
||||
strcpy(el->name, tmp );
|
||||
m_free(tmp);
|
||||
g10_free(tmp);
|
||||
}
|
||||
else {
|
||||
el = m_alloc_clear( sizeof *el + strlen(fname) );
|
||||
el = g10_xcalloc( 1, sizeof *el + strlen(fname) );
|
||||
strcpy(el->name, fname );
|
||||
}
|
||||
/* check whether we have a class hint */
|
||||
|
@ -152,7 +153,7 @@ register_cipher_extension( const char *mainpgm, const char *fname )
|
|||
for(r = extensions; r; r = r->next ) {
|
||||
if( !compare_filenames(r->name, el->name) ) {
|
||||
log_info("extension `%s' already registered\n", el->name );
|
||||
m_free(el);
|
||||
g10_free(el);
|
||||
return;
|
||||
}
|
||||
else if( r->internal )
|
||||
|
@ -180,7 +181,7 @@ register_internal_cipher_extension(
|
|||
{
|
||||
EXTLIST r, el;
|
||||
|
||||
el = m_alloc_clear( sizeof *el + strlen(module_id) );
|
||||
el = g10_xcalloc( 1, sizeof *el + strlen(module_id) );
|
||||
strcpy(el->name, module_id );
|
||||
el->internal = 1;
|
||||
|
||||
|
@ -188,7 +189,7 @@ register_internal_cipher_extension(
|
|||
for(r = extensions; r; r = r->next ) {
|
||||
if( !compare_filenames(r->name, el->name) ) {
|
||||
log_info("extension `%s' already registered\n", el->name );
|
||||
m_free(el);
|
||||
g10_free(el);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -350,13 +351,13 @@ enum_gnupgext_digests( void **enum_context,
|
|||
ENUMCONTEXT *ctx;
|
||||
|
||||
if( !*enum_context ) { /* init context */
|
||||
ctx = m_alloc_clear( sizeof( *ctx ) );
|
||||
ctx = g10_xcalloc( 1, sizeof( *ctx ) );
|
||||
ctx->r = extensions;
|
||||
ctx->reqalgo = *algo;
|
||||
*enum_context = ctx;
|
||||
}
|
||||
else if( !algo ) { /* release the context */
|
||||
m_free(*enum_context);
|
||||
g10_free(*enum_context);
|
||||
*enum_context = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -411,12 +412,12 @@ enum_gnupgext_ciphers( void **enum_context, int *algo,
|
|||
void (**)( void *, byte *, byte *));
|
||||
|
||||
if( !*enum_context ) { /* init context */
|
||||
ctx = m_alloc_clear( sizeof( *ctx ) );
|
||||
ctx = g10_xcalloc( 1, sizeof( *ctx ) );
|
||||
ctx->r = extensions;
|
||||
*enum_context = ctx;
|
||||
}
|
||||
else if( !algo ) { /* release the context */
|
||||
m_free(*enum_context);
|
||||
g10_free(*enum_context);
|
||||
*enum_context = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -485,12 +486,12 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
|
|||
unsigned (**)( int , MPI * ) );
|
||||
|
||||
if( !*enum_context ) { /* init context */
|
||||
ctx = m_alloc_clear( sizeof( *ctx ) );
|
||||
ctx = g10_xcalloc( 1, sizeof( *ctx ) );
|
||||
ctx->r = extensions;
|
||||
*enum_context = ctx;
|
||||
}
|
||||
else if( !algo ) { /* release the context */
|
||||
m_free(*enum_context);
|
||||
g10_free(*enum_context);
|
||||
*enum_context = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
|
@ -79,7 +80,7 @@ test_keys( ELG_secret_key *sk, unsigned nbits )
|
|||
/*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/
|
||||
{ char *p = get_random_bits( nbits, 0, 0 );
|
||||
mpi_set_buffer( test, p, (nbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
g10_free(p);
|
||||
}
|
||||
|
||||
encrypt( out1_a, out1_b, test, &pk );
|
||||
|
@ -119,7 +120,7 @@ gen_k( MPI p )
|
|||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
if( !rndbuf || nbits < 32 ) {
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
rndbuf = get_random_bits( nbits, 1, 1 );
|
||||
}
|
||||
else { /* change only some of the higher bits */
|
||||
|
@ -128,7 +129,7 @@ gen_k( MPI p )
|
|||
* maybe it is easier to do this directly in random.c */
|
||||
char *pp = get_random_bits( 32, 1, 1 );
|
||||
memcpy( rndbuf,pp, 4 );
|
||||
m_free(pp);
|
||||
g10_free(pp);
|
||||
}
|
||||
mpi_set_buffer( k, rndbuf, nbytes, 0 );
|
||||
|
||||
|
@ -156,7 +157,7 @@ gen_k( MPI p )
|
|||
}
|
||||
}
|
||||
found:
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
if( DBG_CIPHER )
|
||||
progress('\n');
|
||||
mpi_free(p_1);
|
||||
|
@ -212,13 +213,13 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
|||
progress('.');
|
||||
if( rndbuf ) { /* change only some of the higher bits */
|
||||
if( nbits < 16 ) {/* should never happen ... */
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
rndbuf = get_random_bits( nbits, 2, 1 );
|
||||
}
|
||||
else {
|
||||
char *r = get_random_bits( 16, 2, 1 );
|
||||
memcpy(rndbuf, r, 16/8 );
|
||||
m_free(r);
|
||||
g10_free(r);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -226,7 +227,7 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
|
|||
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
|
||||
mpi_clear_highbit( x, nbits+1 );
|
||||
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
|
||||
m_free(rndbuf);
|
||||
g10_free(rndbuf);
|
||||
|
||||
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
|
||||
mpi_powm( y, g, x, p );
|
||||
|
@ -443,7 +444,7 @@ elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
|
|||
ELG_secret_key sk;
|
||||
|
||||
if( !is_ELGAMAL(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
|
||||
generate( &sk, nbits, retfactors );
|
||||
skey[0] = sk.p;
|
||||
|
@ -460,16 +461,16 @@ elg_check_secret_key( int algo, MPI *skey )
|
|||
ELG_secret_key sk;
|
||||
|
||||
if( !is_ELGAMAL(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.g = skey[1];
|
||||
sk.y = skey[2];
|
||||
sk.x = skey[3];
|
||||
if( !check_secret_key( &sk ) )
|
||||
return G10ERR_BAD_SECKEY;
|
||||
return GCRYERR_BAD_SECRET_KEY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -482,9 +483,9 @@ elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
|
|||
ELG_public_key pk;
|
||||
|
||||
if( !is_ELGAMAL(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
pk.p = pkey[0];
|
||||
pk.g = pkey[1];
|
||||
|
@ -501,10 +502,10 @@ elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
|
|||
ELG_secret_key sk;
|
||||
|
||||
if( !is_ELGAMAL(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !data[0] || !data[1]
|
||||
|| !skey[0] || !skey[1] || !skey[2] || !skey[3] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.g = skey[1];
|
||||
|
@ -521,9 +522,9 @@ elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||
ELG_secret_key sk;
|
||||
|
||||
if( !is_ELGAMAL(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
sk.p = skey[0];
|
||||
sk.g = skey[1];
|
||||
|
@ -542,16 +543,16 @@ elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
|||
ELG_public_key pk;
|
||||
|
||||
if( !is_ELGAMAL(algo) )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
if( !data[0] || !data[1] || !hash
|
||||
|| !pkey[0] || !pkey[1] || !pkey[2] )
|
||||
return G10ERR_BAD_MPI;
|
||||
return GCRYERR_BAD_MPI;
|
||||
|
||||
pk.p = pkey[0];
|
||||
pk.g = pkey[1];
|
||||
pk.y = pkey[2];
|
||||
if( !verify( data[0], data[1], hash, &pk ) )
|
||||
return G10ERR_BAD_SIGN;
|
||||
return GCRYERR_BAD_SIGNATURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/* g10c.c - Wrapper for cipher functions
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mpi.h"
|
||||
#include "random.h"
|
||||
#include "cipher.h"
|
||||
|
||||
|
||||
/* FIXME: The modules should use functions from libgcrypt */
|
||||
|
||||
|
||||
const char *g10c_revision_string(int dummy) { return "$Revision$"; }
|
||||
|
||||
MPI
|
||||
g10c_generate_secret_prime( unsigned nbits )
|
||||
{
|
||||
return generate_secret_prime( nbits );
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
g10c_get_random_bits( unsigned nbits, int level, int secure )
|
||||
{
|
||||
return (char*)get_random_bits( nbits, level, secure );
|
||||
}
|
||||
|
66
cipher/md.c
66
cipher/md.c
|
@ -28,7 +28,6 @@
|
|||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "errors.h"
|
||||
#include "dynload.h"
|
||||
#include "rmd.h"
|
||||
|
||||
|
@ -93,13 +92,13 @@ new_list_item( int algo,
|
|||
{
|
||||
struct md_digest_list_s *r;
|
||||
|
||||
r = m_alloc_clear( sizeof *r );
|
||||
r = g10_xcalloc( 1, sizeof *r );
|
||||
r->algo = algo,
|
||||
r->name = (*get_info)( algo, &r->contextsize,
|
||||
&r->asnoid, &r->asnlen, &r->mdlen,
|
||||
&r->init, &r->write, &r->final, &r->read );
|
||||
if( !r->name ) {
|
||||
m_free(r);
|
||||
g10_free(r);
|
||||
r = NULL;
|
||||
}
|
||||
return r;
|
||||
|
@ -230,7 +229,7 @@ check_digest_algo( int algo )
|
|||
if( r->algo == algo )
|
||||
return 0;
|
||||
} while( !r && load_digest_module(algo) );
|
||||
return G10ERR_DIGEST_ALGO;
|
||||
return GCRYERR_INV_MD_ALGO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -267,8 +266,13 @@ md_open( int algo, int secure )
|
|||
/ sizeof(PROPERLY_ALIGNED_TYPE) ) * sizeof(PROPERLY_ALIGNED_TYPE);
|
||||
|
||||
/* allocate and set the Context pointer to the private data */
|
||||
hd = secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) )
|
||||
: m_alloc( n + sizeof( struct gcry_md_context ) );
|
||||
hd = secure ? g10_malloc_secure( n + sizeof( struct gcry_md_context ) )
|
||||
: g10_malloc( n + sizeof( struct gcry_md_context ) );
|
||||
if( !hd ) {
|
||||
set_lasterr( GCRYERR_NO_MEM );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hd->ctx = ctx = (struct gcry_md_context*)( (char*)hd + n );
|
||||
/* setup the globally visible data (bctl in the diagram)*/
|
||||
hd->bufsize = n - sizeof( struct gcry_md_handle ) + 1;
|
||||
|
@ -315,13 +319,16 @@ md_enable( GCRY_MD_HD hd, int algo )
|
|||
} while( !r && load_digest_module( algo ) );
|
||||
if( !r ) {
|
||||
log_debug("md_enable: algorithm %d not available\n", algo );
|
||||
return set_lasterr( GCRYERR_INV_ALGO );
|
||||
return set_lasterr( GCRYERR_INV_MD_ALGO );
|
||||
}
|
||||
/* and allocate a new list entry */
|
||||
ac = h->secure? m_alloc_secure( sizeof *ac + r->contextsize
|
||||
ac = h->secure? g10_malloc_secure( sizeof *ac + r->contextsize
|
||||
- sizeof(r->context) )
|
||||
: m_alloc( sizeof *ac + r->contextsize
|
||||
: g10_malloc( sizeof *ac + r->contextsize
|
||||
- sizeof(r->context) );
|
||||
if( !rc )
|
||||
return set_lasterr( GCRYERR_NO_MEM );
|
||||
|
||||
*ac = *r;
|
||||
ac->next = h->list;
|
||||
h->list = ac;
|
||||
|
@ -350,8 +357,13 @@ md_copy( GCRY_MD_HD ahd )
|
|||
md_write( ahd, NULL, 0 );
|
||||
|
||||
n = (char*)ahd->ctx - (char*)ahd;
|
||||
bhd = a->secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) )
|
||||
: m_alloc( n + sizeof( struct gcry_md_context ) );
|
||||
bhd = a->secure ? g10_malloc_secure( n + sizeof( struct gcry_md_context ) )
|
||||
: g10_malloc( n + sizeof( struct gcry_md_context ) );
|
||||
if( !bhd ) {
|
||||
set_lasterr( GCRYERR_NO_MEM );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bhd->ctx = b = (struct gcry_md_context*)( (char*)bhd + n );
|
||||
/* no need to copy the buffer due to the write above */
|
||||
assert( ahd->bufsize == (n - sizeof( struct gcry_md_handle ) + 1) );
|
||||
|
@ -363,9 +375,9 @@ md_copy( GCRY_MD_HD ahd )
|
|||
/* and now copy the complete list of algorithms */
|
||||
/* I know that the copied list is reversed, but that doesn't matter */
|
||||
for( ar=a->list; ar; ar = ar->next ) {
|
||||
br = a->secure ? m_alloc_secure( sizeof *br + ar->contextsize
|
||||
br = a->secure ? g10_xmalloc_secure( sizeof *br + ar->contextsize
|
||||
- sizeof(ar->context) )
|
||||
: m_alloc( sizeof *br + ar->contextsize
|
||||
: g10_xmalloc( sizeof *br + ar->contextsize
|
||||
- sizeof(ar->context) );
|
||||
memcpy( br, ar, sizeof(*br) + ar->contextsize
|
||||
- sizeof(ar->context) );
|
||||
|
@ -412,9 +424,9 @@ md_close(GCRY_MD_HD a)
|
|||
md_stop_debug(a);
|
||||
for(r=a->ctx->list; r; r = r2 ) {
|
||||
r2 = r->next;
|
||||
m_free(r);
|
||||
g10_free(r);
|
||||
}
|
||||
m_free(a);
|
||||
g10_free(a);
|
||||
}
|
||||
|
||||
|
||||
|
@ -555,8 +567,8 @@ md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen )
|
|||
|
||||
/* I don't want to change the interface, so I simply work on a copy
|
||||
* of the context (extra overhead - should be fixed)*/
|
||||
context = a->ctx->secure ? m_alloc_secure( r->contextsize )
|
||||
: m_alloc( r->contextsize );
|
||||
context = a->ctx->secure ? g10_xmalloc_secure( r->contextsize )
|
||||
: g10_xmalloc( r->contextsize );
|
||||
memcpy( context, r->context.c, r->contextsize );
|
||||
(*r->final)( context );
|
||||
digest = (*r->read)( context );
|
||||
|
@ -565,7 +577,7 @@ md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen )
|
|||
buflen = r->mdlen;
|
||||
memcpy( buffer, digest, buflen );
|
||||
|
||||
m_free(context);
|
||||
g10_free(context);
|
||||
return buflen;
|
||||
}
|
||||
#endif
|
||||
|
@ -581,6 +593,20 @@ gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen )
|
|||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Shortcut function to hash a buffer with a given algo. The only supported
|
||||
* algorithm is RIPE-MD. The supplied digest buffer must be large enough
|
||||
* to store the resulting hash. No error is returned, the function will
|
||||
* abort on an invalite algo. DISABLED_ALGOS are ignored here.
|
||||
*/
|
||||
void
|
||||
gcry_md_hash_buffer( int algo, char *digest, const char *buffer, size_t length)
|
||||
{
|
||||
if( algo == GCRY_MD_RMD160 )
|
||||
rmd160_hash_buffer( digest, buffer, length );
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
|
||||
static int
|
||||
md_get_algo( GCRY_MD_HD a )
|
||||
|
@ -636,7 +662,7 @@ gcry_md_get_algo_dlen( int algo )
|
|||
default: {
|
||||
int len = md_digest_length( algo );
|
||||
if( !len )
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_MD_ALGO );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -695,7 +721,7 @@ gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes)
|
|||
return -1;
|
||||
}
|
||||
if( check_digest_algo( algo ) ) {
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
set_lasterr( GCRYERR_INV_MD_ALGO );
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
|
@ -121,7 +122,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
|||
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
|
||||
|
||||
/* allocate an array to hold the factors + 2 for later usage */
|
||||
factors = m_alloc_clear( (n+2) * sizeof *factors );
|
||||
factors = g10_xcalloc_clear( n+2, sizeof *factors );
|
||||
|
||||
/* make a pool of 3n+5 primes (this is an arbitrary value) */
|
||||
m = n*3+5;
|
||||
|
@ -129,7 +130,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
|||
m += 5; /* need some more for DSA */
|
||||
if( m < 25 )
|
||||
m = 25;
|
||||
pool = m_alloc_clear( m * sizeof *pool );
|
||||
pool = g10_xcalloc( m , sizeof *pool );
|
||||
|
||||
/* permutate over the pool of primes */
|
||||
count1=count2=0;
|
||||
|
@ -142,7 +143,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
|||
pool[i] = NULL;
|
||||
}
|
||||
/* init m_out_of_n() */
|
||||
perms = m_alloc_clear( m );
|
||||
perms = g10_xcalloc( 1, m );
|
||||
for(i=0; i < n; i++ ) {
|
||||
perms[i] = 1;
|
||||
pool[i] = gen_prime( fbits, 0, 1 );
|
||||
|
@ -158,7 +159,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
|||
factors[j++] = pool[i];
|
||||
}
|
||||
if( i == n ) {
|
||||
m_free(perms); perms = NULL;
|
||||
g10_free(perms); perms = NULL;
|
||||
progress('!');
|
||||
goto next_try; /* allocate new primes */
|
||||
}
|
||||
|
@ -213,7 +214,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
|||
}
|
||||
|
||||
if( ret_factors ) { /* caller wants the factors */
|
||||
*ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
|
||||
*ret_factors = g10_xcalloc( n+2 , sizeof **ret_factors);
|
||||
if( mode == 1 ) {
|
||||
i = 0;
|
||||
(*ret_factors)[i++] = mpi_copy( q_factor );
|
||||
|
@ -264,11 +265,11 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
|||
if( !DBG_CIPHER )
|
||||
progress('\n');
|
||||
|
||||
m_free( factors ); /* (factors are shallow copies) */
|
||||
g10_free( factors ); /* (factors are shallow copies) */
|
||||
for(i=0; i < m; i++ )
|
||||
mpi_free( pool[i] );
|
||||
m_free( pool );
|
||||
m_free(perms);
|
||||
g10_free( pool );
|
||||
g10_free(perms);
|
||||
mpi_free(val_2);
|
||||
return prime;
|
||||
}
|
||||
|
@ -292,7 +293,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel )
|
|||
for(i=0; small_prime_numbers[i]; i++ )
|
||||
no_of_small_prime_numbers++;
|
||||
}
|
||||
mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
|
||||
mods = g10_xmalloc( no_of_small_prime_numbers * sizeof *mods );
|
||||
/* make nbits fit into MPI implementation */
|
||||
nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
|
||||
val_2 = mpi_alloc_set_ui( 2 );
|
||||
|
@ -308,7 +309,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel )
|
|||
/* generate a random number */
|
||||
{ char *p = get_random_bits( nbits, randomlevel, secret );
|
||||
mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
g10_free(p);
|
||||
}
|
||||
|
||||
/* set high order bit to 1, set low order bit to 1 */
|
||||
|
@ -352,7 +353,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel )
|
|||
mpi_free(result);
|
||||
mpi_free(pminus1);
|
||||
mpi_free(prime);
|
||||
m_free(mods);
|
||||
g10_free(mods);
|
||||
return ptest;
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +437,7 @@ is_prime( MPI n, int steps, int *count )
|
|||
/*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/
|
||||
{ char *p = get_random_bits( nbits, 0, 0 );
|
||||
mpi_set_buffer( x, p, (nbits+7)/8, 0 );
|
||||
m_free(p);
|
||||
g10_free(p);
|
||||
}
|
||||
/* make sure that the number is smaller than the prime
|
||||
* and keep the randomness of the high bit */
|
||||
|
|
426
cipher/pubkey.c
426
cipher/pubkey.c
|
@ -27,13 +27,13 @@
|
|||
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "errors.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
#include "elgamal.h"
|
||||
#include "dsa.h"
|
||||
#include "dynload.h"
|
||||
|
||||
/* FIXME: use set_lasterr() */
|
||||
|
||||
#define TABLE_SIZE 10
|
||||
|
||||
|
@ -58,31 +58,72 @@ struct pubkey_table_s {
|
|||
static struct pubkey_table_s pubkey_table[TABLE_SIZE];
|
||||
static int disabled_algos[TABLE_SIZE];
|
||||
|
||||
static struct { const char* name; int algo;
|
||||
const char* common_elements;
|
||||
const char* public_elements;
|
||||
const char* secret_elements;
|
||||
} algo_info_table[] = {
|
||||
{ "dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x" },
|
||||
{ "rsa" , PUBKEY_ALGO_RSA , "ne", "", "dpqu" },
|
||||
{ "elg" , PUBKEY_ALGO_ELGAMAL , "pgy", "", "x" },
|
||||
{ "openpgp-dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x" },
|
||||
{ "openpgp-rsa" , PUBKEY_ALGO_RSA , "pqgy", "", "x" },
|
||||
{ "openpgp-elg" , PUBKEY_ALGO_ELGAMAL_E , "pgy", "", "x" },
|
||||
{ "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "pgy", "", "x" },
|
||||
{ NULL }};
|
||||
|
||||
static struct {
|
||||
const char* name; int algo;
|
||||
const char* elements;
|
||||
} sig_info_table[] = {
|
||||
{ "dsa" , PUBKEY_ALGO_DSA , "rs" },
|
||||
{ "rsa" , PUBKEY_ALGO_RSA , "s" },
|
||||
{ "elg" , PUBKEY_ALGO_ELGAMAL , "rs" },
|
||||
{ "openpgp-dsa" , PUBKEY_ALGO_DSA , "rs" },
|
||||
{ "openpgp-rsa" , PUBKEY_ALGO_RSA , "s" },
|
||||
{ "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "rs" },
|
||||
{ NULL }};
|
||||
|
||||
static struct {
|
||||
const char* name; int algo;
|
||||
const char* elements;
|
||||
} enc_info_table[] = {
|
||||
{ "elg" , PUBKEY_ALGO_ELGAMAL , "ab" },
|
||||
{ "rsa" , PUBKEY_ALGO_RSA , "a" },
|
||||
{ "openpgp-rsa" , PUBKEY_ALGO_RSA , "a" },
|
||||
{ "openpgp-elg" , PUBKEY_ALGO_ELGAMAL_E , "ab" },
|
||||
{ "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "ab" },
|
||||
{ NULL }};
|
||||
|
||||
|
||||
static int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
|
||||
static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *, MPI), void *opaque );
|
||||
|
||||
static int
|
||||
dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
|
||||
{ log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||
{ log_bug("no generate() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
|
||||
|
||||
static int
|
||||
dummy_check_secret_key( int algo, MPI *skey )
|
||||
{ log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||
{ log_bug("no check_secret_key() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
|
||||
|
||||
static int
|
||||
dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
|
||||
{ log_bug("no encrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||
{ log_bug("no encrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
|
||||
|
||||
static int
|
||||
dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
|
||||
{ log_bug("no decrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||
{ log_bug("no decrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
|
||||
|
||||
static int
|
||||
dummy_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
||||
{ log_bug("no sign() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||
{ log_bug("no sign() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
|
||||
|
||||
static int
|
||||
dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *, MPI), void *opaquev )
|
||||
{ log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||
{ log_bug("no verify() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
|
||||
|
||||
static unsigned
|
||||
dummy_get_nbits( int algo, MPI *pkey )
|
||||
|
@ -269,7 +310,7 @@ gcry_pk_algo_name( int algo )
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
disable_pubkey_algo( int algo )
|
||||
{
|
||||
int i;
|
||||
|
@ -284,38 +325,32 @@ disable_pubkey_algo( int algo )
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
check_pubkey_algo( int algo )
|
||||
{
|
||||
return check_pubkey_algo2( algo, 0 );
|
||||
}
|
||||
|
||||
/****************
|
||||
* a use of 0 means: don't care
|
||||
*/
|
||||
int
|
||||
check_pubkey_algo2( int algo, unsigned use )
|
||||
static int
|
||||
check_pubkey_algo( int algo, unsigned use )
|
||||
{
|
||||
int i;
|
||||
|
||||
do {
|
||||
for(i=0; pubkey_table[i].name; i++ )
|
||||
if( pubkey_table[i].algo == algo ) {
|
||||
if( (use & PUBKEY_USAGE_SIG)
|
||||
&& !(pubkey_table[i].use & PUBKEY_USAGE_SIG) )
|
||||
return G10ERR_WR_PUBKEY_ALGO;
|
||||
if( (use & PUBKEY_USAGE_ENC)
|
||||
&& !(pubkey_table[i].use & PUBKEY_USAGE_ENC) )
|
||||
return G10ERR_WR_PUBKEY_ALGO;
|
||||
if( (use & GCRY_PK_USAGE_SIGN)
|
||||
&& !(pubkey_table[i].use & GCRY_PK_USAGE_SIGN) )
|
||||
return GCRYERR_WRONG_PK_ALGO;
|
||||
if( (use & GCRY_PK_USAGE_ENCR)
|
||||
&& !(pubkey_table[i].use & GCRY_PK_USAGE_ENCR) )
|
||||
return GCRYERR_WRONG_PK_ALGO;
|
||||
|
||||
for(i=0; i < DIM(disabled_algos); i++ ) {
|
||||
if( disabled_algos[i] == algo )
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
}
|
||||
return 0; /* okay */
|
||||
}
|
||||
} while( load_pubkey_modules() );
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,7 +359,7 @@ check_pubkey_algo2( int algo, unsigned use )
|
|||
/****************
|
||||
* Return the number of public key material numbers
|
||||
*/
|
||||
int
|
||||
static int
|
||||
pubkey_get_npkey( int algo )
|
||||
{
|
||||
int i;
|
||||
|
@ -341,7 +376,7 @@ pubkey_get_npkey( int algo )
|
|||
/****************
|
||||
* Return the number of secret key material numbers
|
||||
*/
|
||||
int
|
||||
static int
|
||||
pubkey_get_nskey( int algo )
|
||||
{
|
||||
int i;
|
||||
|
@ -358,7 +393,7 @@ pubkey_get_nskey( int algo )
|
|||
/****************
|
||||
* Return the number of signature material numbers
|
||||
*/
|
||||
int
|
||||
static int
|
||||
pubkey_get_nsig( int algo )
|
||||
{
|
||||
int i;
|
||||
|
@ -375,7 +410,7 @@ pubkey_get_nsig( int algo )
|
|||
/****************
|
||||
* Return the number of encryption material numbers
|
||||
*/
|
||||
int
|
||||
static int
|
||||
pubkey_get_nenc( int algo )
|
||||
{
|
||||
int i;
|
||||
|
@ -391,6 +426,9 @@ pubkey_get_nenc( int algo )
|
|||
|
||||
/****************
|
||||
* Get the number of nbits from the public key
|
||||
* FIXME: This should also take a S-Expt but must be optimized in
|
||||
* some way becuase it is used in keylistsings ans such (store it with the
|
||||
* S-Exp as some private data?)
|
||||
*/
|
||||
unsigned
|
||||
pubkey_nbits( int algo, MPI *pkey )
|
||||
|
@ -419,7 +457,7 @@ pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
|
|||
return (*pubkey_table[i].generate)( algo, nbits,
|
||||
skey, retfactors );
|
||||
} while( load_pubkey_modules() );
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,7 +471,7 @@ pubkey_check_secret_key( int algo, MPI *skey )
|
|||
if( pubkey_table[i].algo == algo )
|
||||
return (*pubkey_table[i].check_secret_key)( algo, skey );
|
||||
} while( load_pubkey_modules() );
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
return GCRYERR_INV_PK_ALGO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,7 +500,7 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
|
|||
goto ready;
|
||||
}
|
||||
} while( load_pubkey_modules() );
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
rc = GCRYERR_INV_PK_ALGO;
|
||||
ready:
|
||||
if( !rc && DBG_CIPHER ) {
|
||||
for(i=0; i < pubkey_get_nenc(algo); i++ )
|
||||
|
@ -501,7 +539,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
|
|||
goto ready;
|
||||
}
|
||||
} while( load_pubkey_modules() );
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
rc = GCRYERR_INV_PK_ALGO;
|
||||
ready:
|
||||
if( !rc && DBG_CIPHER ) {
|
||||
log_mpidump(" plain:", *result );
|
||||
|
@ -516,7 +554,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
|
|||
* should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
|
||||
* algorithm allows this - check with pubkey_get_nsig() )
|
||||
*/
|
||||
int
|
||||
static int
|
||||
pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
||||
{
|
||||
int i, rc;
|
||||
|
@ -535,7 +573,7 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||
goto ready;
|
||||
}
|
||||
} while( load_pubkey_modules() );
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
rc = GCRYERR_INV_PK_ALGO;
|
||||
ready:
|
||||
if( !rc && DBG_CIPHER ) {
|
||||
for(i=0; i < pubkey_get_nsig(algo); i++ )
|
||||
|
@ -548,7 +586,7 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||
* Verify a public key signature.
|
||||
* Return 0 if the signature is good
|
||||
*/
|
||||
int
|
||||
static int
|
||||
pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
||||
int (*cmp)(void *, MPI), void *opaquev )
|
||||
{
|
||||
|
@ -562,12 +600,171 @@ pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
|
|||
goto ready;
|
||||
}
|
||||
} while( load_pubkey_modules() );
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
rc = GCRYERR_INV_PK_ALGO;
|
||||
ready:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
release_mpi_array( MPI *array )
|
||||
{
|
||||
for( ; *array; array++ ) {
|
||||
mpi_free(*array);
|
||||
*array = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Convert a S-Exp with either a private or a public key to our
|
||||
* internal format. Currently we do only support the following
|
||||
* algorithms:
|
||||
* dsa
|
||||
* rsa
|
||||
* openpgp-dsa
|
||||
* openpgp-rsa
|
||||
* openpgp-elg
|
||||
* openpgp-elg-sig
|
||||
* Provide a SE with the first element be either "private-key" or
|
||||
* or "public-key". the followed by a list with its first element
|
||||
* be one of the above algorithm identifiers and the following
|
||||
* elements are pairs with parameter-id and value.
|
||||
* NOTE: we look through the list to find a list beginning with
|
||||
* "private-key" or "public-key" - the first one found is used.
|
||||
*
|
||||
* FIXME: Allow for encrypted secret keys here.
|
||||
*
|
||||
* Returns: A pointer to an allocated array of MPIs if the return value is
|
||||
* zero; the caller has to release this array.
|
||||
*/
|
||||
static int
|
||||
sexp_to_key( GCRY_SEXP sexp, int want_private, MPI **retarray, int *retalgo)
|
||||
{
|
||||
GCRY_SEXP list, l2;
|
||||
const char *name;
|
||||
const char *s;
|
||||
size_t n;
|
||||
int i, idx;
|
||||
int algo;
|
||||
const char *elems1, *elems2;
|
||||
GCRY_MPI *array;
|
||||
|
||||
/* check that the first element is valid */
|
||||
list = gcry_sexp_find_token( sexp, want_private? "private-key"
|
||||
:"public-key", 0 );
|
||||
if( !list )
|
||||
return GCRYERR_INV_OBJ; /* Does not contain a public- or private-key object */
|
||||
list = gcry_sexp_cdr( list );
|
||||
if( !list )
|
||||
return GCRYERR_NO_OBJ; /* no cdr for the key object */
|
||||
name = gcry_sexp_car_data( list, &n );
|
||||
if( !name )
|
||||
return GCRYERR_INV_OBJ; /* invalid structure of object */
|
||||
for(i=0; (s=algo_info_table[i].name); i++ ) {
|
||||
if( strlen(s) == n && !memcmp( s, name, n ) )
|
||||
break;
|
||||
}
|
||||
if( !s )
|
||||
return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
|
||||
algo = algo_info_table[i].algo;
|
||||
elems1 = algo_info_table[i].common_elements;
|
||||
elems2 = want_private? algo_info_table[i].secret_elements
|
||||
: algo_info_table[i].public_elements;
|
||||
array = g10_calloc( (strlen(elems1)+strlen(elems2)+1, sizeof *array );
|
||||
if( !array )
|
||||
return GCRYERR_NO_MEM;
|
||||
|
||||
idx = 0;
|
||||
for(s=elems1; *s; s++, idx++ ) {
|
||||
l2 = gcry_sexp_find_token( list, s, 1 );
|
||||
if( !l2 ) {
|
||||
g10_free( array );
|
||||
return GCRYERR_NO_OBJ; /* required parameter not found */
|
||||
}
|
||||
array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG );
|
||||
if( !array[idx] ) {
|
||||
g10_free( array );
|
||||
return GCRYERR_INV_OBJ; /* required parameter is invalid */
|
||||
}
|
||||
}
|
||||
for(s=elems2; *s; s++, idx++ ) {
|
||||
l2 = gcry_sexp_find_token( list, s, 1 );
|
||||
if( !l2 ) {
|
||||
g10_free( array );
|
||||
return GCRYERR_NO_OBJ; /* required parameter not found */
|
||||
}
|
||||
/* FIXME: put the MPI in secure memory when needed */
|
||||
array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG );
|
||||
if( !array[idx] ) {
|
||||
g10_free( array );
|
||||
return GCRYERR_INV_OBJ; /* required parameter is invalid */
|
||||
}
|
||||
}
|
||||
|
||||
*retarray = array;
|
||||
*retalgo = algo;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sexp_to_sig( GCRY_SEXP sexp, MPI **retarray, int *retalgo)
|
||||
{
|
||||
GCRY_SEXP list, l2;
|
||||
const char *name;
|
||||
const char *s;
|
||||
size_t n;
|
||||
int i, idx;
|
||||
int algo;
|
||||
const char *elems;
|
||||
GCRY_MPI *array;
|
||||
|
||||
/* check that the first element is valid */
|
||||
list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
|
||||
if( !list )
|
||||
return GCRYERR_INV_OBJ; /* Does not contain a signature value object */
|
||||
list = gcry_sexp_cdr( list );
|
||||
if( !list )
|
||||
return GCRYERR_NO_OBJ; /* no cdr for the sig object */
|
||||
name = gcry_sexp_car_data( list, &n );
|
||||
if( !name )
|
||||
return GCRYERR_INV_OBJ; /* invalid structure of object */
|
||||
for(i=0; (s=sig_info_table[i].name); i++ ) {
|
||||
if( strlen(s) == n && !memcmp( s, name, n ) )
|
||||
break;
|
||||
}
|
||||
if( !s )
|
||||
return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
|
||||
algo = sig_info_table[i].algo;
|
||||
elems = sig_info_table[i].elements;
|
||||
array = g10_calloc( (strlen(elems)+1) , sizeof *array );
|
||||
if( !array )
|
||||
return GCRYERR_NO_MEM;
|
||||
|
||||
idx = 0;
|
||||
for(s=elems; *s; s++, idx++ ) {
|
||||
l2 = gcry_sexp_find_token( list, s, 1 );
|
||||
if( !l2 ) {
|
||||
g10_free( array );
|
||||
return GCRYERR_NO_OBJ; /* required parameter not found */
|
||||
}
|
||||
array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG );
|
||||
if( !array[idx] ) {
|
||||
g10_free( array );
|
||||
return GCRYERR_INV_OBJ; /* required parameter is invalid */
|
||||
}
|
||||
}
|
||||
|
||||
*retarray = array;
|
||||
*retalgo = algo;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
gcry_pk_encrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey )
|
||||
{
|
||||
|
@ -582,34 +779,146 @@ gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Create a signature.
|
||||
*
|
||||
* Caller has to provide a secret kez as the SEXP skey and data expressed
|
||||
* as a SEXP list hash with only one emelennt which should instantly be
|
||||
* available as a MPI. Later versions of this functions may provide padding
|
||||
* and other things depending on data.
|
||||
*
|
||||
* Returns: 0 or an errorcode.
|
||||
* In case of 0 the function returns a new SEXP with the
|
||||
* signature value; the structure of this signature depends on the
|
||||
* other arguments but is always suitable to be passed to
|
||||
* gcry_pk_verify
|
||||
*/
|
||||
int
|
||||
gcry_pk_sign( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey )
|
||||
gcry_pk_sign( GCRY_SEXP *r_sig, GCRY_SEXP s_hash, GCRY_SEXP s_skey )
|
||||
{
|
||||
MPI *skey, hash;
|
||||
MPI *result;
|
||||
int i, algo, rc;
|
||||
const char *algo_name, *algo_elems;
|
||||
GCRY_SEXP s;
|
||||
/* get the secret key */
|
||||
s = NULL; /*gcry_sexp_find_token( skey, "private-key", 0 );*/
|
||||
if( !s )
|
||||
return -1; /* no private key */
|
||||
/* ... */
|
||||
|
||||
rc = sexp_to_key( s_skey, 1, &skey, &algo );
|
||||
if( rc )
|
||||
return rc;
|
||||
|
||||
/* get the name and the required size of the result array */
|
||||
for(i=0; (algo_name = sig_info_table[i].name); i++ ) {
|
||||
if( sig_info_table[i].algo == algo )
|
||||
break;
|
||||
}
|
||||
if( !algo_name ) {
|
||||
release_mpi_array( skey );
|
||||
return -4; /* oops: unknown algorithm */
|
||||
}
|
||||
algo_elems = sig_info_table[i].elements;
|
||||
|
||||
/* get the stuff we want to sign */
|
||||
hash = gcry_sexp_car_mpi( s_hash, 0 );
|
||||
if( !hash ) {
|
||||
release_mpi_array( skey );
|
||||
return -1; /* fixme: get a real errorcode for this */
|
||||
}
|
||||
result = g10_xcalloc_clear( (strlen(algo_elems)+1) , sizeof *result );
|
||||
rc = pubkey_sign( algo, result, hash, skey );
|
||||
release_mpi_array( skey );
|
||||
mpi_free( hash );
|
||||
if( rc ) {
|
||||
g10_free( result );
|
||||
return rc;
|
||||
}
|
||||
|
||||
s = SEXP_NEW( algo_name, 0 );
|
||||
for(i=0; algo_elems[i]; i++ ) {
|
||||
char tmp[2];
|
||||
tmp[0] = algo_elems[i];
|
||||
tmp[1] = 0;
|
||||
s = gcry_sexp_append( s, gcry_sexp_new_name_mpi( tmp, result[i] ) );
|
||||
}
|
||||
g10_free( result );
|
||||
*r_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ), s );
|
||||
gcry_sexp_dump( *r_sig );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Verify a sgnature. Caller has to supply the public key pkey,
|
||||
* the signature sig and his hashvalue data. Public key has to be
|
||||
* a standard public key given as an S-Exp, sig is a S-Exp as returned
|
||||
* from gcry_pk_sign and data must be an S-Exp like the one in sign too.
|
||||
*/
|
||||
int
|
||||
gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey )
|
||||
{
|
||||
MPI *pkey, hash, *sig;
|
||||
int algo, sigalgo;
|
||||
int rc;
|
||||
|
||||
rc = sexp_to_key( s_pkey, 0, &pkey, &algo );
|
||||
if( rc )
|
||||
return rc;
|
||||
rc = sexp_to_sig( s_sig, &sig, &sigalgo );
|
||||
if( rc ) {
|
||||
release_mpi_array( pkey );
|
||||
return rc;
|
||||
}
|
||||
if( algo != sigalgo ) {
|
||||
release_mpi_array( pkey );
|
||||
release_mpi_array( sig );
|
||||
return -1; /* fixme: add real errornumber - algo does not match */
|
||||
}
|
||||
|
||||
hash = gcry_sexp_car_mpi( s_hash, 0 );
|
||||
if( !hash ) {
|
||||
release_mpi_array( pkey );
|
||||
release_mpi_array( sig );
|
||||
return -1; /* fixme: get a real errorcode for this */
|
||||
}
|
||||
|
||||
rc = pubkey_verify( algo, hash, sig, pkey, NULL, NULL );
|
||||
release_mpi_array( pkey );
|
||||
release_mpi_array( sig );
|
||||
mpi_free(hash);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gcry_pk_verify( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey )
|
||||
gcry_pk_ctl( int cmd, void *buffer, size_t buflen)
|
||||
{
|
||||
/* ... */
|
||||
switch( cmd ) {
|
||||
case GCRYCTL_DISABLE_ALGO:
|
||||
/* this one expects a buffer pointing to an
|
||||
* integer with the algo number.
|
||||
*/
|
||||
if( !buffer || buflen != sizeof(int) )
|
||||
return set_lasterr( GCRYERR_INV_CIPHER_ALGO );
|
||||
disable_pubkey_algo( *(int*)buffer );
|
||||
break;
|
||||
|
||||
default:
|
||||
return set_lasterr( GCRYERR_INV_OP );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Return information about the given algorithm
|
||||
* WHAT select the kind of information returned:
|
||||
* GCRYCTL_TEST_ALGO:
|
||||
* Returns 0 when the specified algorithm is available for use.
|
||||
* buffer and nbytes must be zero.
|
||||
* Buffer must be NULL, nbytes may have the address of a variable
|
||||
* with the required usage of the algorithm. It may be 0 for don't
|
||||
* care or a combination of the GCRY_PK_USAGE_xxx flags;
|
||||
*
|
||||
* On error the value -1 is returned and the error reason may be
|
||||
* retrieved by gcry_errno().
|
||||
|
@ -623,17 +932,24 @@ int
|
|||
gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes)
|
||||
{
|
||||
switch( what ) {
|
||||
case GCRYCTL_TEST_ALGO:
|
||||
if( buffer || nbytes ) {
|
||||
set_lasterr( GCRYERR_INV_ARG );
|
||||
return -1;
|
||||
}
|
||||
if( check_pubkey_algo( algo ) ) {
|
||||
set_lasterr( GCRYERR_INV_ALGO );
|
||||
return -1;
|
||||
case GCRYCTL_TEST_ALGO: {
|
||||
int use = nbytes? *nbytes: 0;
|
||||
if( buffer ) {
|
||||
set_lasterr( GCRYERR_INV_ARG );
|
||||
return -1;
|
||||
}
|
||||
if( check_pubkey_algo( algo, use ) ) {
|
||||
set_lasterr( GCRYERR_INV_PK_ALGO );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GCRYCTL_GET_ALGO_NPKEY: return pubkey_get_npkey( algo );
|
||||
case GCRYCTL_GET_ALGO_NSKEY: return pubkey_get_nskey( algo );
|
||||
case GCRYCTL_GET_ALGO_NSIGN: return pubkey_get_nsig( algo );
|
||||
case GCRYCTL_GET_ALGO_NENCR: return pubkey_get_nenc( algo );
|
||||
|
||||
default:
|
||||
set_lasterr( GCRYERR_INV_OP );
|
||||
return -1;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#ifdef HAVE_GETRUSAGE
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "rmd.h"
|
||||
#include "ttyio.h"
|
||||
|
@ -97,6 +98,7 @@ static int quick_test;
|
|||
static int faked_rng;
|
||||
|
||||
|
||||
static byte *get_random_bytes( size_t nbytes, int level, int secure );
|
||||
static void read_pool( byte *buffer, size_t length, int level );
|
||||
static void add_randomness( const void *buffer, size_t length, int source );
|
||||
static void random_poll(void);
|
||||
|
@ -123,10 +125,10 @@ initialize(void)
|
|||
/* The data buffer is allocated somewhat larger, so that
|
||||
* we can use this extra space (which is allocated in secure memory)
|
||||
* as a temporary hash buffer */
|
||||
rndpool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
|
||||
: m_alloc_clear(POOLSIZE+BLOCKLEN);
|
||||
keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
|
||||
: m_alloc_clear(POOLSIZE+BLOCKLEN);
|
||||
rndpool = secure_alloc ? g10_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
|
||||
: g10_xcalloc(1,POOLSIZE+BLOCKLEN);
|
||||
keypool = secure_alloc ? g10_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
|
||||
: g10_xcalloc(1,POOLSIZE+BLOCKLEN);
|
||||
is_initialized = 1;
|
||||
cipher_modules_constructor();
|
||||
}
|
||||
|
@ -170,11 +172,11 @@ quick_random_gen( int onoff )
|
|||
* for most usage, 2 is good for key generation stuff but may be very slow.
|
||||
*/
|
||||
void
|
||||
randomize_buffer( byte *buffer, size_t length, int level )
|
||||
gcry_randomize( byte *buffer, size_t length, enum gcry_random_level level )
|
||||
{
|
||||
char *p = get_random_bits( length*8, level, 1 );
|
||||
char *p = get_random_bytes( length, level, 1 );
|
||||
memcpy( buffer, p, length );
|
||||
m_free(p);
|
||||
g10_free(p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -191,11 +193,10 @@ random_is_faked()
|
|||
* caller must free the buffer.
|
||||
* Note: The returned value is rounded up to bytes.
|
||||
*/
|
||||
byte *
|
||||
get_random_bits( size_t nbits, int level, int secure )
|
||||
static byte *
|
||||
get_random_bytes( size_t nbytes, int level, int secure )
|
||||
{
|
||||
byte *buf, *p;
|
||||
size_t nbytes = (nbits+7)/8;
|
||||
|
||||
if( quick_test && level > 1 )
|
||||
level = 1;
|
||||
|
@ -209,7 +210,8 @@ get_random_bits( size_t nbits, int level, int secure )
|
|||
rndstats.ngetbytes2++;
|
||||
}
|
||||
|
||||
buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes );
|
||||
buf = secure && secure_alloc ? g10_xmalloc_secure( nbytes )
|
||||
: g10_xmalloc( nbytes );
|
||||
for( p = buf; nbytes > 0; ) {
|
||||
size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
|
||||
read_pool( p, n, level );
|
||||
|
@ -219,6 +221,18 @@ get_random_bits( size_t nbits, int level, int secure )
|
|||
return buf;
|
||||
}
|
||||
|
||||
void *
|
||||
gcry_random_bytes( size_t nbytes, enum gcry_random_level level )
|
||||
{
|
||||
return get_random_bytes( nbytes, level, 0 );
|
||||
}
|
||||
|
||||
void *
|
||||
gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level )
|
||||
{
|
||||
return get_random_bytes( nbytes, level, 1 );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Mix the pool
|
||||
|
@ -461,7 +475,7 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
|
|||
#endif
|
||||
}
|
||||
|
||||
p = buffer = m_alloc( length );
|
||||
p = buffer = g10_xmalloc( length );
|
||||
n = length;
|
||||
#ifdef HAVE_RAND
|
||||
while( n-- )
|
||||
|
@ -471,7 +485,7 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
|
|||
*p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
|
||||
#endif
|
||||
add_randomness( buffer, length, requester );
|
||||
m_free(buffer);
|
||||
g10_free(buffer);
|
||||
return 0; /* okay */
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ void random_dump_stats(void);
|
|||
void secure_random_alloc(void);
|
||||
int quick_random_gen( int onoff );
|
||||
int random_is_faked(void);
|
||||
void randomize_buffer( byte *buffer, size_t length, int level );
|
||||
byte *get_random_bits( size_t nbits, int level, int secure );
|
||||
void fast_random_poll( void );
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "ttyio.h"
|
||||
#include "dynload.h"
|
||||
|
@ -126,7 +127,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
|
|||
if( connect( fd, (struct sockaddr*)&addr, addr_len) == -1 )
|
||||
g10_log_fatal("can't connect to `%s': %s\n",
|
||||
name, strerror(errno) );
|
||||
m_free(name);
|
||||
g10_free(name);
|
||||
}
|
||||
do_restart = 0;
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
code base to be maintained */
|
||||
|
||||
|
||||
/* Fixme: We use plain mallocs here beucase it may be used as a module
|
||||
* should be changed. *
|
||||
|
||||
/* General includes */
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
@ -126,7 +127,7 @@ load_and_init_winseed( void )
|
|||
g10_log_info("fast buffer size=%u\n", n2);
|
||||
|
||||
entropy_buffer_size = n1 > n2? n1: n2;
|
||||
entropy_buffer = m_alloc( entropy_buffer_size );
|
||||
entropy_buffer = g10_xmalloc( entropy_buffer_size );
|
||||
g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );
|
||||
|
||||
return;
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
#include <string.h> /* for memcmp() */
|
||||
|
||||
#include "types.h" /* for byte and u32 typedefs */
|
||||
#include "g10lib.h"
|
||||
#include "util.h"
|
||||
#include "errors.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
||||
|
@ -574,7 +574,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
|
|||
|
||||
/* Check key length. */
|
||||
if( ( ( keylen - 16 ) | 16 ) != 16 )
|
||||
return G10ERR_WRONG_KEYLEN;
|
||||
return GCRYERR_INV_KEYLEN;
|
||||
|
||||
/* Do self-test if necessary. */
|
||||
if (!initialized) {
|
||||
|
@ -584,7 +584,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
|
|||
fprintf(stderr, "%s\n", selftest_failed );
|
||||
}
|
||||
if( selftest_failed )
|
||||
return G10ERR_SELFTEST_FAILED;
|
||||
return GCRYERR_SELFTEST;
|
||||
|
||||
/* Compute the first two words of the S vector. The magic numbers are
|
||||
* the entries of the RS matrix, preprocessed through poly_to_exp. The
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue