pluto and scepclient use the random plugin from libstrongswan

This commit is contained in:
Andreas Steffen 2009-04-30 18:31:48 +00:00
parent 8af25c56af
commit bc2e33ca96
28 changed files with 381 additions and 2075 deletions

View File

@ -957,6 +957,7 @@ if test x$fips_prf = xtrue; then
fi
if test x$random = xtrue; then
libstrongswan_plugins=${libstrongswan_plugins}" random"
pluto_plugins=${pluto_plugins}" random"
fi
if test x$x509 = xtrue; then
libstrongswan_plugins=${libstrongswan_plugins}" x509"

View File

@ -61,10 +61,15 @@
#include <settings.h>
#include <plugins/plugin_loader.h>
#include <crypto/crypto_factory.h>
#include <credentials/credential_factory.h>
#include <fetcher/fetcher_manager.h>
#include <database/database_factory.h>
#ifdef NO_CREDENTIAL_FACTORY
typedef struct credential_factory_t credential_factory_t;
#else
#include <credentials/credential_factory.h>
#endif
typedef struct library_t library_t;
/**

View File

@ -67,7 +67,6 @@ static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
{
char error[CURL_ERROR_SIZE];
char buf[256];
status_t status;
*result = chunk_empty;

View File

@ -18,11 +18,8 @@ db_ops.c db_ops.h \
defs.c defs.h \
demux.c demux.h \
dnskey.c dnskey.h \
dsa.c dsa.h \
elgamal.c elgamal.h \
fetch.c fetch.h \
foodgroups.c foodgroups.h \
gcryptfix.c gcryptfix.h \
id.c id.h \
ike_alg.c ike_alg.h \
ipsec_doi.c ipsec_doi.h \
@ -47,7 +44,6 @@ pgp.c pgp.h \
pkcs1.c pkcs1.h \
pkcs7.c pkcs7.h \
plutomain.c \
primegen.c smallprime.c \
rcv_whack.c rcv_whack.h \
server.c server.h \
sha1.c sha1.h \
@ -86,6 +82,7 @@ AM_CFLAGS = \
-DPLUGINS=\""${pluto_plugins}\"" \
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
-DNO_CREDENTIAL_FACTORY \
-DPLUTO -DKLIPS -DDEBUG
pluto_LDADD = \

View File

@ -1363,3 +1363,7 @@ void init_constants(void)
happy(initsubnet(&ipv4_any, 0, '0', &ipv4_all));
happy(initsubnet(&ipv6_any, 0, '0', &ipv6_all));
}
u_char secret_of_the_day[SHA1_DIGEST_SIZE];

View File

@ -1268,4 +1268,7 @@ enum dns_auth_level {
/* natt traversal types */
extern const char *const natt_type_bitnames[];
/* secret value for responder cookies */
extern u_char secret_of_the_day[SHA1_DIGEST_SIZE];
#endif /* _CONSTANTS_H */

View File

@ -21,10 +21,12 @@
#include <freeswan.h>
#include <library.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
#include "sha1.h"
#include "rnd.h"
#include "cookie.h"
const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
@ -33,8 +35,8 @@ const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
* First argument is true if we're to create an Initiator cookie.
* Length SHOULD be a multiple of sizeof(u_int32_t).
*/
void
get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
void get_cookie(bool initiator, u_int8_t *cookie, int length,
const ip_address *addr)
{
u_char buffer[SHA1_DIGEST_SIZE];
SHA1_CTX ctx;
@ -42,7 +44,11 @@ get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
do {
if (initiator)
{
get_rnd_bytes(cookie, length);
rng_t *rng;
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
rng->get_bytes(rng, length, cookie);
rng->destroy(rng);
}
else /* Responder cookie */
{

View File

@ -1,476 +0,0 @@
/* dsa.c - DSA signature scheme
* 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
*/
#ifdef PLUTO
#include <gmp.h>
#include <freeswan.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "rnd.h"
#include "gcryptfix.h"
#else /*! PLUTO */
/* #include <config.h> */
#endif /* !PLUTO */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef PLUTO
/* #include <assert.h> */
/* #include "util.h" */
/* #include "mpi.h" */
/* #include "cipher.h" */
#endif
#include "dsa.h"
typedef struct {
MPI p; /* prime */
MPI q; /* group order */
MPI g; /* group generator */
MPI y; /* g^x mod p */
} DSA_public_key;
typedef struct {
MPI p; /* prime */
MPI q; /* group order */
MPI g; /* group generator */
MPI y; /* g^x mod p */
MPI x; /* secret exponent */
} DSA_secret_key;
static MPI gen_k( MPI q );
static void test_keys( DSA_secret_key *sk, unsigned qbits );
static int check_secret_key( DSA_secret_key *sk );
static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
static void
progress( int c )
{
fputc( c, stderr );
}
/****************
* Generate a random secret exponent k less than q
*/
static MPI
gen_k( MPI q )
{
MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
unsigned int nbits = mpi_get_nbits(q);
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
if( DBG_CIPHER )
log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER )
progress('.');
if( !rndbuf || nbits < 32 ) {
m_free(rndbuf);
rndbuf = get_random_bits( nbits, 1, 1 );
}
else { /* change only some of the higher bits */
/* we could imporove this by directly requesting more memory
* at the first call to get_random_bits() and use this the here
* 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);
}
mpi_set_buffer( k, rndbuf, nbytes, 0 );
if( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else {
mpi_set_highbit( k, nbits-1 );
mpi_clear_bit( k, nbits-1 );
}
if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */
if( DBG_CIPHER )
progress('+');
continue; /* no */
}
if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
if( DBG_CIPHER )
progress('-');
continue; /* no */
}
break; /* okay */
}
m_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
return k;
}
static void
test_keys( DSA_secret_key *sk, unsigned qbits )
{
DSA_public_key pk;
MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
pk.p = sk->p;
pk.q = sk->q;
pk.g = sk->g;
pk.y = sk->y;
/*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);
}
sign( out1_a, out1_b, test, sk );
if( !verify( out1_a, out1_b, test, &pk ) )
log_fatal("DSA:: sign, verify failed\n");
mpi_free( test );
mpi_free( out1_a );
mpi_free( out1_b );
}
/****************
* Generate a DSA key pair with a key of size NBITS
* Returns: 2 structures filled with all needed values
* and an array with the n-1 factors of (p-1)
*/
static void
generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
{
MPI p; /* the prime */
MPI q; /* the 160 bit prime factor */
MPI g; /* the generator */
MPI y; /* g^x mod p */
MPI x; /* the secret exponent */
MPI h, e; /* helper */
unsigned qbits;
byte *rndbuf;
assert( nbits >= 512 && nbits <= 1024 );
qbits = 160;
p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
/* get q out of factors */
q = mpi_copy((*ret_factors)[0]);
if( mpi_get_nbits(q) != qbits )
BUG();
/* find a generator g (h and e are helpers)*/
/* e = (p-1)/q */
e = mpi_alloc( mpi_get_nlimbs(p) );
mpi_sub_ui( e, p, 1 );
mpi_fdiv_q( e, e, q );
g = mpi_alloc( mpi_get_nlimbs(p) );
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
do {
mpi_add_ui( h, h, 1 );
/* g = h^e mod p */
mpi_powm( g, h, e, p );
} while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
/* select a random number which has these properties:
* 0 < x < q-1
* This must be a very good random number because this
* is the secret part. */
if( DBG_CIPHER )
log_debug("choosing a random x ");
assert( qbits >= 160 );
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
rndbuf = NULL;
do {
if( DBG_CIPHER )
progress('.');
if( !rndbuf )
rndbuf = get_random_bits( qbits, 2, 1 );
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);
}
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);
mpi_free( e );
mpi_free( h );
/* y = g^x mod p */
y = mpi_alloc( mpi_get_nlimbs(p) );
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) {
progress('\n');
log_mpidump("dsa p= ", p );
log_mpidump("dsa q= ", q );
log_mpidump("dsa g= ", g );
log_mpidump("dsa y= ", y );
log_mpidump("dsa x= ", x );
}
/* copy the stuff to the key structures */
sk->p = p;
sk->q = q;
sk->g = g;
sk->y = y;
sk->x = x;
/* now we can test our keys (this should never fail!) */
test_keys( sk, qbits );
}
/****************
* Test whether the secret key is valid.
* Returns: if this is a valid key.
*/
static int
check_secret_key( DSA_secret_key *sk )
{
int rc;
MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
}
/****************
* Make a DSA signature from HASH and put it into r and s.
*/
static void
sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
{
MPI k;
MPI kinv;
MPI tmp;
/* select a random k with 0 < k < q */
k = gen_k( skey->q );
/* r = (a^k mod p) mod q */
mpi_powm( r, skey->g, k, skey->p );
mpi_fdiv_r( r, r, skey->q );
/* kinv = k^(-1) mod q */
kinv = mpi_alloc( mpi_get_nlimbs(k) );
mpi_invm(kinv, k, skey->q );
/* s = (kinv * ( hash + x * r)) mod q */
tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
mpi_mul( tmp, skey->x, r );
mpi_add( tmp, tmp, hash );
mpi_mulm( s , kinv, tmp, skey->q );
mpi_free(k);
mpi_free(kinv);
mpi_free(tmp);
}
/****************
* Returns true if the signature composed from R and S is valid.
*/
static int
verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
{
int rc;
MPI w, u1, u2, v;
MPI base[3];
MPI exp[3];
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
return 0; /* assertion 0 < r < q failed */
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
return 0; /* assertion 0 < s < q failed */
w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
/* w = s^(-1) mod q */
mpi_invm( w, s, pkey->q );
/* u1 = (hash * w) mod q */
mpi_mulm( u1, hash, w, pkey->q );
/* u2 = r * w mod q */
mpi_mulm( u2, r, w, pkey->q );
/* v = g^u1 * y^u2 mod p mod q */
base[0] = pkey->g; exp[0] = u1;
base[1] = pkey->y; exp[1] = u2;
base[2] = NULL; exp[2] = NULL;
mpi_mulpowm( v, base, exp, pkey->p );
mpi_fdiv_r( v, v, pkey->q );
rc = !mpi_cmp( v, r );
mpi_free(w);
mpi_free(u1);
mpi_free(u2);
mpi_free(v);
return rc;
}
/*********************************************
************** interface ******************
*********************************************/
int
dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{
DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
generate( &sk, nbits, retfactors );
skey[0] = sk.p;
skey[1] = sk.q;
skey[2] = sk.g;
skey[3] = sk.y;
skey[4] = sk.x;
return 0;
}
int
dsa_check_secret_key( int algo, MPI *skey )
{
DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY;
return 0;
}
int
dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
{
DSA_secret_key sk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
return G10ERR_BAD_MPI;
sk.p = skey[0];
sk.q = skey[1];
sk.g = skey[2];
sk.y = skey[3];
sk.x = skey[4];
resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
sign( resarr[0], resarr[1], data, &sk );
return 0;
}
int
dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
{
DSA_public_key pk;
if( algo != PUBKEY_ALGO_DSA )
return G10ERR_PUBKEY_ALGO;
if( !data[0] || !data[1] || !hash
|| !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
return G10ERR_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 0;
}
unsigned
dsa_get_nbits( int algo, MPI *pkey )
{
if( algo != PUBKEY_ALGO_DSA )
return 0;
return mpi_get_nbits( pkey[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.
* Usage: Bit 0 set : allows signing
* 1 set : allows encryption
*/
const char *
dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
int *use )
{
*npkey = 4;
*nskey = 5;
*nenc = 0;
*nsig = 2;
switch( algo ) {
case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
default: *use = 0; return NULL;
}
}

View File

@ -1,32 +0,0 @@
/* dsa.h - DSA signature scheme
* 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
*/
#ifndef G10_DSA_H
#define G10_DSA_H
int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
int dsa_check_secret_key( int algo, MPI *skey );
int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev );
unsigned dsa_get_nbits( int algo, MPI *pkey );
const char *dsa_get_info( int algo, int *npkey, int *nskey,
int *nenc, int *nsig, int *use );
#endif /*G10_DSA_H*/

View File

@ -28,7 +28,6 @@
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "rnd.h"
#include "gcryptfix.h"
#else /*! PLUTO */
/* #include <config.h> */

View File

@ -1,281 +0,0 @@
/* Routines to make gcrypt routines feel at home in Pluto.
* Copyright (C) 1999 D. Hugh Redelmeier.
*
* This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program 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.
*/
#include <stdlib.h>
#include <gmp.h>
#include <freeswan.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "rnd.h"
#include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */
MPI
mpi_alloc( unsigned nlimbs UNUSED )
{
MPI n = malloc(sizeof *n);
mpz_init(n);
return n;
}
MPI
mpi_alloc_secure( unsigned nlimbs )
{
return mpi_alloc(nlimbs);
}
MPI
mpi_alloc_set_ui( unsigned long u)
{
MPI n = malloc(sizeof *n);
mpz_init_set_ui(n, u);
return n;
}
MPI
mpi_copy( MPI a )
{
MPI n = malloc(sizeof *n);
mpz_init_set(n, a);
return n;
}
void
mpi_free( MPI a )
{
mpz_clear(a);
free(a);
}
int
mpi_divisible_ui(MPI dividend, ulong divisor )
{
ulong rem;
mpz_t remtoo;
mpz_init(remtoo);
rem = mpz_mod_ui(remtoo, dividend, divisor);
mpz_clear(remtoo);
return rem == 0;
}
unsigned
mpi_trailing_zeros( MPI a )
{
return mpz_scan1(a, 0);
}
unsigned
mpi_get_nbits( MPI a )
{
return mpz_sizeinbase(a, 2);
}
int
mpi_test_bit( MPI a, unsigned n )
{
/* inspired by gmp/mpz/clrbit.c */
mp_size_t li = n / mp_bits_per_limb;
if (li >= a->_mp_size)
return 0;
return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
}
void
mpi_set_bit( MPI a, unsigned n )
{
mpz_setbit(a, n);
}
void
mpi_clear_bit( MPI a, unsigned n )
{
mpz_clrbit(a, n);
}
void
mpi_clear_highbit( MPI a, unsigned n )
{
/* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n);
}
void
mpi_set_highbit( MPI a, unsigned n )
{
/* This seems whacky, but what do I know. */
mpz_fdiv_r_2exp(a, a, n+1);
mpz_setbit(a, n);
}
void
mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
{
/* this is a lot like n_to_mpz */
size_t i;
passert(sign == 0); /* we won't hit any negative numbers */
mpz_init_set_ui(a, 0);
for (i = 0; i != nbytes; i++)
{
mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
mpz_add_ui(a, a, buffer[i]);
}
}
u_char *
get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
{
size_t nbytes = (nbits+7)/8;
u_char *b = malloc(nbytes);
get_rnd_bytes(b, nbytes);
return b;
}
/**************** from gnupg-1.0.0/mpi/mpi-mpow.c
* RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
*/
#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) mpi_mulm( (w), (u), (v), (m) )
static int
build_index( MPI *exparray, int k, int i, int t )
{
int j, bitno;
int index = 0;
bitno = t-i;
for(j=k-1; j >= 0; j-- ) {
index <<= 1;
if( mpi_test_bit( exparray[j], bitno ) )
index |= 1;
}
/*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
return index;
}
void
mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
{
int k; /* number of elements */
int t; /* bit size of largest exponent */
int i, j, idx;
MPI *G; /* table with precomputed values of size 2^k */
MPI tmp;
#ifdef USE_BARRETT
MPI barrett_y, barrett_r1, barrett_r2;
int barrett_k;
#endif
for(k=0; basearray[k]; k++ )
;
passert(k);
for(t=0, i=0; (tmp=exparray[i]); i++ ) {
/*log_mpidump("exp: ", tmp );*/
j = mpi_get_nbits(tmp);
if( j > t )
t = j;
}
/*log_mpidump("mod: ", m );*/
passert(i==k);
passert(t);
passert( k < 10 );
#ifdef PLUTO
m_alloc_ptrs_clear(G, 1<<k);
#else
G = m_alloc_clear( (1<<k) * sizeof *G );
#endif
#ifdef USE_BARRETT
barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
#endif
/* and calculate */
tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
mpi_set_ui( res, 1 );
for(i = 1; i <= t; i++ ) {
barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
barrett_r1, barrett_r2 );
idx = build_index( exparray, k, i, t );
passert( idx >= 0 && idx < (1<<k) );
if( !G[idx] ) {
if( !idx )
G[0] = mpi_alloc_set_ui( 1 );
else {
for(j=0; j < k; j++ ) {
if( (idx & (1<<j) ) ) {
if( !G[idx] )
G[idx] = mpi_copy( basearray[j] );
else
barrett_mulm( G[idx], G[idx], basearray[j],
m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
}
if( !G[idx] )
G[idx] = mpi_alloc(0);
}
}
barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
}
/* cleanup */
mpi_free(tmp);
#ifdef USE_BARRETT
mpi_free(barrett_y);
mpi_free(barrett_r1);
mpi_free(barrett_r2);
#endif
for(i=0; i < (1<<k); i++ )
mpi_free(G[i]);
m_free(G);
}
void
log_mpidump( const char *text UNUSED, MPI a )
{
/* Print number in hex -- helpful to see if they match bytes.
* Humans are not going to do arithmetic with the large numbers!
* Much code adapted from mpz_to_n.
*/
u_char buf[8048]; /* this ought to be big enough */
size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
MP_INT temp1, temp2;
int i;
passert(len <= sizeof(buf));
mpz_init(&temp1);
mpz_init(&temp2);
mpz_set(&temp1, a);
for (i = len-1; i >= 0; i--)
{
buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
mpz_set(&temp1, &temp2);
}
passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
mpz_clear(&temp1);
mpz_clear(&temp2);
#ifdef DEBUG
DBG_dump(text, buf, len);
#endif /* DEBUG */
}

View File

@ -1,109 +0,0 @@
/* Definitions to make gcrypt routines feel at home in Pluto.
* Copyright (C) 1999 D. Hugh Redelmeier.
*
* This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program 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.
*/
#define DBG_CIPHER 1 /* some day we'll do this right */
/* Simulate MPI routines with gmp routines.
* gmp's MP_INT is a stuct; MPI's MPI is a pointer to an analogous struct.
* gmp's mpz_t is an array of one of these structs to enable magic pointer
* conversions to make the notation convenient (but confusing).
*/
typedef u_char byte;
typedef MP_INT *MPI;
#define BITS_PER_MPI_LIMB mp_bits_per_limb
extern MPI mpi_alloc( unsigned nlimbs );
extern MPI mpi_alloc_secure( unsigned nlimbs );
#define mpi_alloc_like(n) mpi_alloc(mpi_get_nlimbs(n))
extern MPI mpi_alloc_set_ui( unsigned long u);
#define mpi_set_ui(w, u) mpz_set_ui(w, u)
#define mpi_set(w, u) mpz_set(w, u)
extern void mpi_free( MPI a );
extern MPI mpi_copy( MPI a );
extern unsigned mpi_get_nbits( MPI a );
#define mpi_get_nlimbs(a) ((a)->_mp_alloc) /* dirty, but useless */
extern void mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign );
extern unsigned mpi_trailing_zeros( MPI a );
extern int mpi_test_bit( MPI a, unsigned n );
extern void mpi_set_bit( MPI a, unsigned n );
extern void mpi_clear_bit( MPI a, unsigned n );
extern void mpi_clear_highbit( MPI a, unsigned n );
extern void mpi_set_highbit( MPI a, unsigned n );
#define mpi_cmp_ui(u, v) mpz_cmp_ui((u), (v))
#define mpi_cmp(u, v) mpz_cmp((u), (v))
#define mpi_is_neg(n) (mpz_sgn(n) < 0)
#define mpi_add(w, u, v) mpz_add((w), (u), (v))
#define mpi_add_ui(w, u, v) mpz_add_ui((w), (u), (v))
#define mpi_sub_ui(w, u, v) mpz_sub_ui((w), (u), (v))
#define mpi_subm( w, u, v, m) { mpz_sub( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
#define mpi_mul( w, u, v) mpz_mul( (w), (u), (v))
#define mpi_mul_ui( w, u, v) mpz_mul_ui( (w), (u), (v))
#define mpi_mulm( w, u, v, m) { mpz_mul( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
#define mpi_fdiv_q(quot, dividend, divisor) mpz_fdiv_q((quot), (dividend), (divisor))
#define mpi_fdiv_r( rem, dividend, divisor ) mpz_fdiv_r( (rem), (dividend), (divisor) )
#define mpi_fdiv_r_ui( rem, dividend, divisor ) mpz_fdiv_r_ui( (rem), (dividend), (divisor) )
#define mpi_tdiv_q_2exp( w, u, count ) mpz_tdiv_q_2exp( (w), (u), (count) )
extern int mpi_divisible_ui(MPI dividend, ulong divisor );
#define mpi_powm( res, base, exp, mod) mpz_powm( res, base, exp, mod)
extern void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
#define mpi_gcd( g, a, b ) ( mpz_gcd( (g), (a), (b) ), !mpi_cmp_ui( (g), 1))
#define mpi_invm( x, a, n ) mpz_invert( (x), (a), (n) )
#ifdef DEBUG
# define log_debug(f...) DBG_log(f)
#else
# define log_debug(f...) do ; while (0) /* do nothing, carefully */
#endif
#define log_fatal(f...) exit_log(f) /* overreaction? */
extern void log_mpidump( const char *text, MPI a );
#define assert(p) passert(p)
#define BUG() passert(FALSE)
#define m_alloc_ptrs_clear(pp, n) { \
int c = (n); \
(pp) = malloc((n) * sizeof(*(pp))); \
while (c > 0) (pp)[--c] = NULL; \
}
extern u_char *get_random_bits(size_t nbits, int level, int secure);
#define m_alloc(sz) malloc((sz)) /* not initialized */
#define m_free(n) free(n) /* always freeing something from get_random_bits */
/* declarations from gnupg-1.0.0/include/cipher.h */
/*-- primegen.c --*/
MPI generate_secret_prime( unsigned nbits );
MPI generate_public_prime( unsigned nbits );
MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
MPI g, MPI **factors );
#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not for v3)*/
#define PUBKEY_ALGO_DSA 17
#define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */
#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
/* from gnupg-1.0.0/include/errors.h */
#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
#define G10ERR_BAD_SECKEY 7 /* Bad secret key */
#define G10ERR_BAD_SIGN 8 /* Bad signature */
#define G10ERR_BAD_MPI 30
/*-- smallprime.c --*/
extern ushort small_prime_numbers[];

View File

@ -28,7 +28,10 @@
#include <freeswan.h>
#include <ipsec_policy.h>
#include <library.h>
#include <asn1/asn1.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
@ -52,7 +55,6 @@
#include "server.h"
#include "spdb.h"
#include "timer.h"
#include "rnd.h"
#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "whack.h"
#include "fetch.h"
@ -120,9 +122,8 @@ echo_hdr(struct msg_digest *md, bool enc, u_int8_t np)
* We make the leap that the length should be that of the group
* (see quoted passage at start of ACCEPT_KE).
*/
static void
compute_dh_shared(struct state *st, const chunk_t g
, const struct oakley_group_desc *group)
static void compute_dh_shared(struct state *st, const chunk_t g,
const struct oakley_group_desc *group)
{
MP_INT mp_g, mp_shared;
struct timeval tv0, tv1;
@ -158,16 +159,19 @@ compute_dh_shared(struct state *st, const chunk_t g
/* if we haven't already done so, compute a local DH secret (st->st_sec) and
* the corresponding public value (g). This is emitted as a KE payload.
*/
static bool
build_and_ship_KE(struct state *st, chunk_t *g
, const struct oakley_group_desc *group, pb_stream *outs, u_int8_t np)
static bool build_and_ship_KE(struct state *st, chunk_t *g,
const struct oakley_group_desc *group,
pb_stream *outs, u_int8_t np)
{
if (!st->st_sec_in_use)
{
u_char tmp[LOCALSECRETSIZE];
MP_INT mp_g;
get_rnd_bytes(tmp, LOCALSECRETSIZE);
rng_t *rng;
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
rng->get_bytes(rng, LOCALSECRETSIZE, tmp);
rng->destroy(rng);
st->st_sec_in_use = TRUE;
n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE);
@ -192,10 +196,9 @@ build_and_ship_KE(struct state *st, chunk_t *g
* Diffie-Hellman group enforced, if necessary, by pre-pending the
* value with zeros.
*/
static notification_t
accept_KE(chunk_t *dest, const char *val_name
, const struct oakley_group_desc *gr
, pb_stream *pbs)
static notification_t accept_KE(chunk_t *dest, const char *val_name,
const struct oakley_group_desc *gr,
pb_stream *pbs)
{
if (pbs_left(pbs) != gr->bytes)
{
@ -216,9 +219,8 @@ accept_KE(chunk_t *dest, const char *val_name
* Check and accept optional Quick Mode KE payload for PFS.
* Extends ACCEPT_PFS to check whether KE is allowed or required.
*/
static notification_t
accept_PFS_KE(struct msg_digest *md, chunk_t *dest
, const char *val_name, const char *msg_name)
static notification_t accept_PFS_KE(struct msg_digest *md, chunk_t *dest,
const char *val_name, const char *msg_name)
{
struct state *st = md->st;
struct payload_digest *const ke_pd = md->chain[ISAKMP_NEXT_KE];
@ -249,18 +251,20 @@ accept_PFS_KE(struct msg_digest *md, chunk_t *dest
return NOTHING_WRONG;
}
static bool
build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np
, const char *name)
static bool build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np,
const char *name)
{
rng_t *rng;
free(n->ptr);
*n = chunk_create(malloc(DEFAULT_NONCE_SIZE), DEFAULT_NONCE_SIZE);
get_rnd_bytes(n->ptr, DEFAULT_NONCE_SIZE);
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
rng->get_bytes(rng, DEFAULT_NONCE_SIZE, n->ptr);
rng->destroy(rng);
return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name);
}
static bool
collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
static bool collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
{
struct connection *d = find_host_connection(&md->iface->addr
, pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY);
@ -295,8 +299,8 @@ collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
return *top != NULL;
}
static bool
build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
static bool build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs,
u_int8_t np)
{
pb_stream cr_pbs;
struct isakmp_cr cr_hd;
@ -321,10 +325,10 @@ build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
* whether to send the notification, based on the type and the
* destination, if we care to.
*/
static void
send_notification(struct state *sndst, u_int16_t type, struct state *encst,
msgid_t msgid, u_char *icookie, u_char *rcookie,
u_char *spi, size_t spisize, u_char protoid)
static void send_notification(struct state *sndst, u_int16_t type,
struct state *encst, msgid_t msgid,
u_char *icookie, u_char *rcookie,
u_char *spi, size_t spisize, u_char protoid)
{
u_char buffer[1024];
pb_stream pbs, r_hdr_pbs;
@ -451,9 +455,8 @@ send_notification(struct state *sndst, u_int16_t type, struct state *encst,
}
}
void
send_notification_from_state(struct state *st, enum state_kind state,
u_int16_t type)
void send_notification_from_state(struct state *st, enum state_kind state,
u_int16_t type)
{
struct state *p1st;
@ -487,8 +490,7 @@ send_notification_from_state(struct state *st, enum state_kind state,
}
}
void
send_notification_from_md(struct msg_digest *md, u_int16_t type)
void send_notification_from_md(struct msg_digest *md, u_int16_t type)
{
/**
* Create a dummy state to be able to use send_packet in
@ -519,8 +521,7 @@ send_notification_from_md(struct msg_digest *md, u_int16_t type)
* inbound IPSEC SAs. Does nothing if no such SAs are being deleted.
* Delete Notifications cannot announce deletion of outbound IPSEC/ISAKMP SAs.
*/
void
send_delete(struct state *st)
void send_delete(struct state *st)
{
pb_stream reply_pbs;
pb_stream r_hdr_pbs;
@ -686,8 +687,8 @@ send_delete(struct state *st)
}
}
void
accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
void accept_delete(struct state *st, struct msg_digest *md,
struct payload_digest *p)
{
struct isakmp_delete *d = &(p->payload.delete);
size_t sizespi;
@ -869,8 +870,7 @@ accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
* rfc2408 3.6 Transform Payload.
* Note: it talks about 4 BYTE boundaries!
*/
void
close_message(pb_stream *pbs)
void close_message(pb_stream *pbs)
{
size_t padding = pad_up(pbs_offset(pbs), 4);
@ -1062,12 +1062,8 @@ main_outI1(int whack_sock, struct connection *c, struct state *predecessor
return STF_OK;
}
void
ipsecdoi_initiate(int whack_sock
, struct connection *c
, lset_t policy
, unsigned long try
, so_serial_t replacing)
void ipsecdoi_initiate(int whack_sock, struct connection *c, lset_t policy,
unsigned long try, so_serial_t replacing)
{
/* If there's already an ISAKMP SA established, use that and
* go directly to Quick Mode. We are even willing to use one
@ -1114,8 +1110,7 @@ ipsecdoi_initiate(int whack_sock
* - duplicate whack fd, if live.
* Does not delete the old state -- someone else will do that.
*/
void
ipsecdoi_replace(struct state *st, unsigned long try)
void ipsecdoi_replace(struct state *st, unsigned long try)
{
int whack_sock = dup_any(st->st_whack_sock);
lset_t policy = st->st_policy;
@ -1160,8 +1155,7 @@ ipsecdoi_replace(struct state *st, unsigned long try)
/* SKEYID for preshared keys.
* See draft-ietf-ipsec-ike-01.txt 4.1
*/
static bool
skeyid_preshared(struct state *st)
static bool skeyid_preshared(struct state *st)
{
const chunk_t *pss = get_preshared_secret(st->st_connection);
@ -1206,8 +1200,7 @@ skeyid_digisig(struct state *st)
/* Generate the SKEYID_* and new IV
* See draft-ietf-ipsec-ike-01.txt 4.1
*/
static bool
generate_skeyids_iv(struct state *st)
static bool generate_skeyids_iv(struct state *st)
{
/* Generate the SKEYID */
switch (st->st_oakley.auth)
@ -1347,12 +1340,10 @@ generate_skeyids_iv(struct state *st)
*/
typedef void (*hash_update_t)(union hash_ctx *, const u_char *, size_t) ;
static void
main_mode_hash_body(struct state *st
, bool hashi /* Initiator? */
, const pb_stream *idpl /* ID payload, as PBS */
, union hash_ctx *ctx
, void (*hash_update_void)(void *, const u_char *input, size_t))
static void main_mode_hash_body(struct state *st, bool hashi,
const pb_stream *idpl, union hash_ctx *ctx,
void (*hash_update_void)(void *, const u_char *input, size_t))
{
#define HASH_UPDATE_T (union hash_ctx *, const u_char *input, unsigned int len)
hash_update_t hash_update=(hash_update_t) hash_update_void;
@ -1401,10 +1392,8 @@ main_mode_hash_body(struct state *st
}
static size_t /* length of hash */
main_mode_hash(struct state *st
, u_char *hash_val /* resulting bytes */
, bool hashi /* Initiator? */
, const pb_stream *idpl) /* ID payload, as PBS; cur must be at end */
main_mode_hash(struct state *st, u_char *hash_val, bool hashi,
const pb_stream *idpl)
{
struct hmac_ctx ctx;
@ -1438,10 +1427,8 @@ main_mode_sha1(struct state *st
* Use PKCS#1 version 1.5 encryption of hash (called
* RSAES-PKCS1-V1_5) in PKCS#2.
*/
static size_t
RSA_sign_hash(struct connection *c
, u_char sig_val[RSA_MAX_OCTETS]
, const u_char *hash_val, size_t hash_len)
static size_t RSA_sign_hash(struct connection *c, u_char sig_val[RSA_MAX_OCTETS],
const u_char *hash_val, size_t hash_len)
{
size_t sz = 0;
smartcard_t *sc = c->spd.this.sc;
@ -1511,10 +1498,9 @@ RSA_sign_hash(struct connection *c
* it is not: the knowledge of the private key allows more efficient (i.e.
* different) computation for encryption.
*/
static err_t
try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN], size_t hash_len
, const pb_stream *sig_pbs, pubkey_t *kr
, struct state *st)
static err_t try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN],
size_t hash_len, const pb_stream *sig_pbs,
pubkey_t *kr, struct state *st)
{
const u_char *sig_val = sig_pbs->cur;
size_t sig_len = pbs_left(sig_pbs);
@ -1644,10 +1630,8 @@ struct tac_state {
char *tn; /* roof of tried[] */
};
static bool
take_a_crack(struct tac_state *s
, pubkey_t *kr
, const char *story USED_BY_DEBUG)
static bool take_a_crack(struct tac_state *s, pubkey_t *kr,
const char *story USED_BY_DEBUG)
{
err_t ugh = try_RSA_signature(s->hash_val, s->hash_len, s->sig_pbs
, kr, s->st);
@ -1679,17 +1663,13 @@ take_a_crack(struct tac_state *s
}
}
static stf_status
RSA_check_signature(const struct id* peer
, struct state *st
, const u_char hash_val[MAX_DIGEST_LEN]
, size_t hash_len
, const pb_stream *sig_pbs
static stf_status RSA_check_signature(const struct id* peer, struct state *st,
const u_char hash_val[MAX_DIGEST_LEN],
size_t hash_len, const pb_stream *sig_pbs,
#ifdef USE_KEYRR
, const pubkey_list_t *keys_from_dns
const pubkey_list_t *keys_from_dns,
#endif /* USE_KEYRR */
, const struct gw_info *gateways_from_dns
)
const struct gw_info *gateways_from_dns)
{
const struct connection *c = st->st_connection;
struct tac_state s;
@ -1838,8 +1818,8 @@ RSA_check_signature(const struct id* peer
}
}
static notification_t
accept_nonce(struct msg_digest *md, chunk_t *dest, const char *name)
static notification_t accept_nonce(struct msg_digest *md, chunk_t *dest,
const char *name)
{
pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
size_t len = pbs_left(nonce_pbs);
@ -1902,9 +1882,9 @@ encrypt_message(pb_stream *pbs, struct state *st)
* Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
* (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
*/
static size_t
quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
, const struct state *st, const msgid_t *msgid, bool hash2)
static size_t quick_mode_hash12(u_char *dest, const u_char *start,
const u_char *roof, const struct state *st,
const msgid_t *msgid, bool hash2)
{
struct hmac_ctx ctx;
@ -1935,8 +1915,7 @@ quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
* NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
* Message ID and Nonces. This is a mistake.
*/
static size_t
quick_mode_hash3(u_char *dest, struct state *st)
static size_t quick_mode_hash3(u_char *dest, struct state *st)
{
struct hmac_ctx ctx;
@ -1953,8 +1932,7 @@ quick_mode_hash3(u_char *dest, struct state *st)
/* Compute Phase 2 IV.
* Uses Phase 1 IV from st_iv; puts result in st_new_iv.
*/
void
init_phase2_iv(struct state *st, const msgid_t *msgid)
void init_phase2_iv(struct state *st, const msgid_t *msgid)
{
const struct hash_desc *h = st->st_oakley.hasher;
union hash_ctx ctx;
@ -1981,9 +1959,8 @@ init_phase2_iv(struct state *st, const msgid_t *msgid)
* Note: this is not called from demux.c
*/
static bool
emit_subnet_id(ip_subnet *net
, u_int8_t np, u_int8_t protoid, u_int16_t port, pb_stream *outs)
static bool emit_subnet_id(ip_subnet *net, u_int8_t np, u_int8_t protoid,
u_int16_t port, pb_stream *outs)
{
struct isakmp_ipsec_id id;
pb_stream id_pbs;
@ -2018,13 +1995,9 @@ emit_subnet_id(ip_subnet *net
return TRUE;
}
stf_status
quick_outI1(int whack_sock
, struct state *isakmp_sa
, struct connection *c
, lset_t policy
, unsigned long try
, so_serial_t replacing)
stf_status quick_outI1(int whack_sock, struct state *isakmp_sa,
struct connection *c, lset_t policy, unsigned long try,
so_serial_t replacing)
{
struct state *st = duplicate_state(isakmp_sa);
pb_stream reply; /* not really a reply */
@ -2236,8 +2209,7 @@ quick_outI1(int whack_sock
/*
* Decode the CERT payload of Phase 1.
*/
static void
decode_cert(struct msg_digest *md)
static void decode_cert(struct msg_digest *md)
{
struct payload_digest *p;
@ -2291,8 +2263,7 @@ decode_cert(struct msg_digest *md)
/*
* Decode the CR payload of Phase 1.
*/
static void
decode_cr(struct msg_digest *md, struct connection *c)
static void decode_cr(struct msg_digest *md, struct connection *c)
{
struct payload_digest *p;
@ -2342,8 +2313,7 @@ decode_cr(struct msg_digest *md, struct connection *c)
* We must be called before SIG or HASH are decoded since we
* may change the peer's RSA key or ID.
*/
static bool
decode_peer_id(struct msg_digest *md, struct id *peer)
static bool decode_peer_id(struct msg_digest *md, struct id *peer)
{
struct state *const st = md->st;
struct payload_digest *const id_pld = md->chain[ISAKMP_NEXT_ID];
@ -2457,8 +2427,8 @@ decode_peer_id(struct msg_digest *md, struct id *peer)
* - if the initiation was explicit, we'd be ignoring user's intent
* - if opportunistic, we'll lose our HOLD info
*/
static bool
switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
static bool switch_connection(struct msg_digest *md, struct id *peer,
bool initiator)
{
struct state *const st = md->st;
struct connection *c = st->st_connection;
@ -2569,11 +2539,8 @@ switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
* Rejects 0.0.0.0/32 or IPv6 equivalent because
* (1) it is wrong and (2) we use this value for inband signalling.
*/
static bool
decode_net_id(struct isakmp_ipsec_id *id
, pb_stream *id_pbs
, ip_subnet *net
, const char *which)
static bool decode_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
ip_subnet *net, const char *which)
{
const struct af_info *afi = NULL;
@ -2737,14 +2704,9 @@ decode_net_id(struct isakmp_ipsec_id *id
}
/* like decode, but checks that what is received matches what was sent */
static bool
check_net_id(struct isakmp_ipsec_id *id
, pb_stream *id_pbs
, u_int8_t *protoid
, u_int16_t *port
, ip_subnet *net
, const char *which)
static bool check_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
u_int8_t *protoid, u_int16_t *port, ip_subnet *net,
const char *which)
{
ip_subnet net_temp;
@ -2763,8 +2725,7 @@ check_net_id(struct isakmp_ipsec_id *id
/*
* look for the existence of a non-expiring preloaded public key
*/
static bool
has_preloaded_public_key(struct state *st)
static bool has_preloaded_public_key(struct state *st)
{
struct connection *c = st->st_connection;
@ -2797,10 +2758,8 @@ has_preloaded_public_key(struct state *st)
* RFC 2409 "IKE" section 5.5
* specifies how this is to be done.
*/
static void
compute_proto_keymat(struct state *st
, u_int8_t protoid
, struct ipsec_proto_info *pi)
static void compute_proto_keymat(struct state *st, u_int8_t protoid,
struct ipsec_proto_info *pi)
{
size_t needed_len = 0; /* bytes of keying material needed */
@ -2945,8 +2904,7 @@ compute_proto_keymat(struct state *st
DBG_dump("Peer KEYMAT computed:\n", pi->peer_keymat, pi->keymat_len));
}
static void
compute_keymats(struct state *st)
static void compute_keymats(struct state *st)
{
if (st->st_ah.present)
compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah);
@ -3245,8 +3203,7 @@ main_inI1_outR1(struct msg_digest *md)
*
* We must verify that the proposal received matches one we sent.
*/
stf_status
main_inR1_outI2(struct msg_digest *md)
stf_status main_inR1_outI2(struct msg_digest *md)
{
struct state *const st = md->st;
@ -3346,8 +3303,7 @@ main_inR1_outI2(struct msg_digest *md)
* HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
* --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
*/
stf_status
main_inI2_outR2(struct msg_digest *md)
stf_status main_inI2_outR2(struct msg_digest *md)
{
struct state *const st = md->st;
pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
@ -3487,8 +3443,7 @@ main_inI2_outR2(struct msg_digest *md)
* SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
* --> HDR*, HASH_I
*/
stf_status
main_inR2_outI3(struct msg_digest *md)
stf_status main_inR2_outI3(struct msg_digest *md)
{
struct state *const st = md->st;
pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
@ -3672,8 +3627,8 @@ struct key_continuation {
typedef stf_status (key_tail_fn)(struct msg_digest *md
, struct key_continuation *kc);
static void
report_key_dns_failure(struct id *id, err_t ugh)
static void report_key_dns_failure(struct id *id, err_t ugh)
{
char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
@ -3843,10 +3798,8 @@ main_id_and_auth(struct msg_digest *md
* to find authentication, or we run out of things
* to try.
*/
static void
key_continue(struct adns_continuation *cr
, err_t ugh
, key_tail_fn *tail)
static void key_continue(struct adns_continuation *cr, err_t ugh,
key_tail_fn *tail)
{
struct key_continuation *kc = (void *)cr;
struct state *st = kc->md->st;
@ -3898,14 +3851,12 @@ key_continue(struct adns_continuation *cr
*/
static key_tail_fn main_inI3_outR3_tail; /* forward */
stf_status
main_inI3_outR3(struct msg_digest *md)
stf_status main_inI3_outR3(struct msg_digest *md)
{
return main_inI3_outR3_tail(md, NULL);
}
static void
main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
static void main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
{
key_continue(cr, ugh, main_inI3_outR3_tail);
}
@ -4077,21 +4028,18 @@ main_inI3_outR3_tail(struct msg_digest *md
static key_tail_fn main_inR3_tail; /* forward */
stf_status
main_inR3(struct msg_digest *md)
stf_status main_inR3(struct msg_digest *md)
{
return main_inR3_tail(md, NULL);
}
static void
main_inR3_continue(struct adns_continuation *cr, err_t ugh)
static void main_inR3_continue(struct adns_continuation *cr, err_t ugh)
{
key_continue(cr, ugh, main_inR3_tail);
}
static stf_status
main_inR3_tail(struct msg_digest *md
, struct key_continuation *kc)
static stf_status main_inR3_tail(struct msg_digest *md,
struct key_continuation *kc)
{
struct state *const st = md->st;
@ -4233,8 +4181,7 @@ struct verify_oppo_continuation {
static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b
, struct adns_continuation *ac);
stf_status
quick_inI1_outR1(struct msg_digest *md)
stf_status quick_inI1_outR1(struct msg_digest *md)
{
const struct state *const p1st = md->st;
struct connection *c = p1st->st_connection;
@ -4341,8 +4288,7 @@ report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
, fgwb, cb, which, ugh);
}
static void
quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
static void quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
{
stf_status r;
struct verify_oppo_continuation *vc = (void *)cr;
@ -4372,9 +4318,8 @@ quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
cur_state = NULL;
}
static stf_status
quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
, enum verify_oppo_step next_step)
static stf_status quick_inI1_outR1_start_query(struct verify_oppo_bundle *b,
enum verify_oppo_step next_step)
{
struct msg_digest *md = b->md;
struct state *p1st = md->st;
@ -4489,10 +4434,10 @@ quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
}
}
static enum verify_oppo_step
quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
, struct adns_continuation *ac
, struct state *p1st)
static enum verify_oppo_step quick_inI1_outR1_process_answer(
struct verify_oppo_bundle *b,
struct adns_continuation *ac,
struct state *p1st)
{
struct connection *c = p1st->st_connection;
enum verify_oppo_step next_step = vos_our_client;
@ -4665,9 +4610,8 @@ quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
return next_step;
}
static stf_status
quick_inI1_outR1_tail(struct verify_oppo_bundle *b
, struct adns_continuation *ac)
static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
struct adns_continuation *ac)
{
struct msg_digest *md = b->md;
struct state *const p1st = md->st;
@ -5019,8 +4963,7 @@ quick_inI1_outR1_tail(struct verify_oppo_bundle *b
/*
* Initialize RFC 3706 Dead Peer Detection
*/
static void
dpd_init(struct state *st)
static void dpd_init(struct state *st)
{
struct state *p1st = find_state(st->st_icookie, st->st_rcookie
, &st->st_connection->spd.that.host_addr, 0);
@ -5044,8 +4987,7 @@ dpd_init(struct state *st)
* (see RFC 2409 "IKE" 5.5)
* Installs inbound and outbound IPsec SAs, routing, etc.
*/
stf_status
quick_inR1_outI2(struct msg_digest *md)
stf_status quick_inR1_outI2(struct msg_digest *md)
{
struct state *const st = md->st;
const struct connection *c = st->st_connection;
@ -5197,8 +5139,7 @@ quick_inR1_outI2(struct msg_digest *md)
* (see RFC 2409 "IKE" 5.5)
* Installs outbound IPsec SAs, routing, etc.
*/
stf_status
quick_inI2(struct msg_digest *md)
stf_status quick_inI2(struct msg_digest *md)
{
struct state *const st = md->st;
@ -5243,9 +5184,8 @@ quick_inI2(struct msg_digest *md)
return STF_OK;
}
static stf_status
send_isakmp_notification(struct state *st, u_int16_t type
, const void *data, size_t len)
static stf_status send_isakmp_notification(struct state *st, u_int16_t type,
const void *data, size_t len)
{
msgid_t msgid;
pb_stream reply;
@ -5350,8 +5290,7 @@ send_isakmp_notification(struct state *st, u_int16_t type
/*
* DPD Out Initiator
*/
void
dpd_outI(struct state *p2st)
void dpd_outI(struct state *p2st)
{
struct state *st;
u_int32_t seqno;
@ -5411,8 +5350,12 @@ dpd_outI(struct state *p2st)
if (!st->st_dpd_seqno)
{
rng_t *rng;
/* Get a non-zero random value that has room to grow */
get_rnd_bytes((u_char *)&st->st_dpd_seqno, sizeof(st->st_dpd_seqno));
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
rng->get_bytes(rng, sizeof(st->st_dpd_seqno), (u_char *)&st->st_dpd_seqno);
rng->destroy(rng);
st->st_dpd_seqno &= 0x7fff;
st->st_dpd_seqno++;
}
@ -5512,8 +5455,8 @@ dpd_inI_outR(struct state *st, struct isakmp_notification *const n, pb_stream *p
/*
* DPD out Responder
*/
stf_status
dpd_inR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
stf_status dpd_inR(struct state *st, struct isakmp_notification *const n,
pb_stream *pbs)
{
u_int32_t seqno;

View File

@ -31,6 +31,9 @@
#include <freeswan.h>
#include <ipsec_policy.h>
#include <library.h>
#include <crypto/rngs/rng.h>
#ifdef KLIPS
#include <signal.h>
#include <sys/time.h> /* for select(2) */
@ -42,7 +45,6 @@
#include "constants.h"
#include "defs.h"
#include "rnd.h"
#include "id.h"
#include "connections.h"
#include "state.h"
@ -118,8 +120,7 @@ struct bare_shunt {
static struct bare_shunt *bare_shunts = NULL;
#ifdef DEBUG
static void
DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
static void DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
{
DBG(DBG_KLIPS,
{
@ -150,14 +151,12 @@ DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
struct eroute_info *orphaned_holds = NULL;
/* forward declaration */
static bool shunt_eroute(struct connection *c
, struct spd_route *sr
, enum routing_t rt_kind
, unsigned int op, const char *opname);
static void set_text_said(char *text_said
, const ip_address *dst
, ipsec_spi_t spi
, int proto);
static bool shunt_eroute(struct connection *c, struct spd_route *sr,
enum routing_t rt_kind, unsigned int op,
const char *opname);
static void set_text_said(char *text_said, const ip_address *dst,
ipsec_spi_t spi, int proto);
bool no_klips = FALSE; /* don't actually use KLIPS */
@ -174,11 +173,9 @@ static const struct pfkey_proto_info null_proto_info[2] = {
}
};
void
record_and_initiate_opportunistic(const ip_subnet *ours
, const ip_subnet *his
, int transport_proto
, const char *why)
void record_and_initiate_opportunistic(const ip_subnet *ours,
const ip_subnet *his,
int transport_proto, const char *why)
{
passert(samesubnettype(ours, his));
@ -279,25 +276,31 @@ static unsigned get_proto_reqid(unsigned base, int proto)
* check if the number was previously used (assuming that no
* SPI lives longer than 4G of its successors).
*/
ipsec_spi_t
get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr,
bool tunnel)
{
static ipsec_spi_t spi = 0; /* host order, so not returned directly! */
char text_said[SATOT_BUF];
rng_t *rng;
set_text_said(text_said, &sr->this.host_addr, 0, proto);
if (kernel_ops->get_spi)
{
return kernel_ops->get_spi(&sr->that.host_addr
, &sr->this.host_addr, proto, tunnel
, get_proto_reqid(sr->reqid, proto)
, IPSEC_DOI_SPI_OUR_MIN, 0xffffffff
, text_said);
}
spi++;
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
while (spi < IPSEC_DOI_SPI_OUR_MIN || spi == ntohl(avoid))
get_rnd_bytes((u_char *)&spi, sizeof(spi));
{
rng->get_bytes(rng, sizeof(spi), (u_char *)&spi);
}
rng->destroy(rng);
DBG(DBG_CONTROL,
{
ipsec_spi_t spi_net = htonl(spi);
@ -316,28 +319,30 @@ get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
* If we can't find one easily, return 0 (a bad SPI,
* no matter what order) indicating failure.
*/
ipsec_spi_t
get_my_cpi(struct spd_route *sr, bool tunnel)
ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel)
{
static cpi_t
first_busy_cpi = 0,
latest_cpi;
static cpi_t first_busy_cpi = 0, latest_cpi;
char text_said[SATOT_BUF];
rng_t *rng;
set_text_said(text_said, &sr->this.host_addr, 0, IPPROTO_COMP);
if (kernel_ops->get_spi)
{
return kernel_ops->get_spi(&sr->that.host_addr
, &sr->this.host_addr, IPPROTO_COMP, tunnel
, get_proto_reqid(sr->reqid, IPPROTO_COMP)
, IPCOMP_FIRST_NEGOTIATED, IPCOMP_LAST_NEGOTIATED
, text_said);
}
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
while (!(IPCOMP_FIRST_NEGOTIATED <= first_busy_cpi && first_busy_cpi < IPCOMP_LAST_NEGOTIATED))
{
get_rnd_bytes((u_char *)&first_busy_cpi, sizeof(first_busy_cpi));
rng->get_bytes(rng, sizeof(first_busy_cpi), (u_char *)&first_busy_cpi);
latest_cpi = first_busy_cpi;
}
rng->destroy(rng);
latest_cpi++;
@ -387,8 +392,8 @@ get_my_cpi(struct spd_route *sr, bool tunnel)
# define DEFAULT_UPDOWN "ipsec _updown"
#endif
static bool
do_command(struct connection *c, struct spd_route *sr, const char *verb)
static bool do_command(struct connection *c, struct spd_route *sr,
const char *verb)
{
char cmd[1536]; /* arbitrary limit on shell command length */
const char *verb_suffix;
@ -647,8 +652,7 @@ enum routability {
route_farconflict = 3
};
static enum routability
could_route(struct connection *c)
static enum routability could_route(struct connection *c)
{
struct spd_route *esr, *rosr;
struct connection *ero /* who, if anyone, owns our eroute? */
@ -792,8 +796,7 @@ could_route(struct connection *c)
return route_easy;
}
bool
trap_connection(struct connection *c)
bool trap_connection(struct connection *c)
{
switch (could_route(c))
{
@ -818,9 +821,10 @@ trap_connection(struct connection *c)
return FALSE;
}
/* delete any eroute for a connection and unroute it if route isn't shared */
void
unroute_connection(struct connection *c)
/**
* Delete any eroute for a connection and unroute it if route isn't shared
*/
void unroute_connection(struct connection *c)
{
struct spd_route *sr;
enum routing_t cr;
@ -849,8 +853,8 @@ unroute_connection(struct connection *c)
#ifdef KLIPS
static void
set_text_said(char *text_said, const ip_address *dst, ipsec_spi_t spi, int proto)
static void set_text_said(char *text_said, const ip_address *dst,
ipsec_spi_t spi, int proto)
{
ip_said said;
@ -862,8 +866,9 @@ set_text_said(char *text_said, const ip_address *dst, ipsec_spi_t spi, int proto
* Trick: return a pointer to the pointer to the entry;
* this allows the entry to be deleted.
*/
static struct bare_shunt **
bare_shunt_ptr(const ip_subnet *ours, const ip_subnet *his, int transport_proto)
static struct bare_shunt** bare_shunt_ptr(const ip_subnet *ours,
const ip_subnet *his,
int transport_proto)
{
struct bare_shunt *p, **pp;
@ -880,8 +885,7 @@ bare_shunt_ptr(const ip_subnet *ours, const ip_subnet *his, int transport_proto)
}
/* free a bare_shunt entry, given a pointer to the pointer */
static void
free_bare_shunt(struct bare_shunt **pp)
static void free_bare_shunt(struct bare_shunt **pp)
{
if (pp == NULL)
{
@ -933,19 +937,18 @@ show_shunt_status(void)
* op is one of the ERO_* operators.
*/
static bool
raw_eroute(const ip_address *this_host
, const ip_subnet *this_client
, const ip_address *that_host
, const ip_subnet *that_client
, ipsec_spi_t spi
, unsigned int proto
, unsigned int satype
, unsigned int transport_proto
, const struct pfkey_proto_info *proto_info
, time_t use_lifetime
, unsigned int op
, const char *opname USED_BY_DEBUG)
static bool raw_eroute(const ip_address *this_host,
const ip_subnet *this_client,
const ip_address *that_host,
const ip_subnet *that_client,
ipsec_spi_t spi,
unsigned int proto,
unsigned int satype,
unsigned int transport_proto,
const struct pfkey_proto_info *proto_info,
time_t use_lifetime,
unsigned int op,
const char *opname USED_BY_DEBUG)
{
char text_said[SATOT_BUF];
@ -971,8 +974,8 @@ raw_eroute(const ip_address *this_host
}
/* test to see if %hold remains */
bool
has_bare_hold(const ip_address *src, const ip_address *dst, int transport_proto)
bool has_bare_hold(const ip_address *src, const ip_address *dst,
int transport_proto)
{
ip_subnet this_client, that_client;
struct bare_shunt **bspp;
@ -989,13 +992,9 @@ has_bare_hold(const ip_address *src, const ip_address *dst, int transport_proto)
/* Replace (or delete) a shunt that is in the bare_shunts table.
* Issues the PF_KEY commands and updates the bare_shunts table.
*/
bool
replace_bare_shunt(const ip_address *src, const ip_address *dst
, policy_prio_t policy_prio
, ipsec_spi_t shunt_spi /* in host order! */
, bool repl /* if TRUE, replace; if FALSE, delete */
, unsigned int transport_proto
, const char *why)
bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
policy_prio_t policy_prio, ipsec_spi_t shunt_spi,
bool repl, unsigned int transport_proto, const char *why)
{
ip_subnet this_client, that_client;
ip_subnet this_broad_client, that_broad_client;
@ -1060,11 +1059,10 @@ replace_bare_shunt(const ip_address *src, const ip_address *dst
}
}
static bool
eroute_connection(struct spd_route *sr
, ipsec_spi_t spi, unsigned int proto, unsigned int satype
, const struct pfkey_proto_info *proto_info
, unsigned int op, const char *opname)
static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
unsigned int proto, unsigned int satype,
const struct pfkey_proto_info *proto_info,
unsigned int op, const char *opname)
{
const ip_address *peer = &sr->that.host_addr;
char buf2[256];
@ -1084,11 +1082,10 @@ eroute_connection(struct spd_route *sr
/* assign a bare hold to a connection */
bool
assign_hold(struct connection *c USED_BY_DEBUG
, struct spd_route *sr
, int transport_proto
, const ip_address *src, const ip_address *dst)
bool assign_hold(struct connection *c USED_BY_DEBUG, struct spd_route *sr,
int transport_proto,
const ip_address *src,
const ip_address *dst)
{
/* either the automatically installed %hold eroute is broad enough
* or we try to add a broader one and delete the automatic one.
@ -1143,9 +1140,8 @@ assign_hold(struct connection *c USED_BY_DEBUG
}
/* install or remove eroute for SA Group */
static bool
sag_eroute(struct state *st, struct spd_route *sr
, unsigned op, const char *opname)
static bool sag_eroute(struct state *st, struct spd_route *sr,
unsigned op, const char *opname)
{
u_int inner_proto = 0;
u_int inner_satype = 0;
@ -1259,11 +1255,9 @@ shunt_policy_spi(struct connection *c, bool prospective)
* If negotiation has failed, the choice between %trap/%pass/%drop/%reject
* is specified in the policy of connection c.
*/
static bool
shunt_eroute(struct connection *c
, struct spd_route *sr
, enum routing_t rt_kind
, unsigned int op, const char *opname)
static bool shunt_eroute(struct connection *c, struct spd_route *sr,
enum routing_t rt_kind,
unsigned int op, const char *opname)
{
/* We are constructing a special SAID for the eroute.
* The destination doesn't seem to matter, but the family does.
@ -1355,8 +1349,7 @@ shunt_eroute(struct connection *c
* The task here is to remove the ":p" part so that the rest can be read
* by another routine.
*/
static const char *
read_proto(const char * s, size_t * len, int * transport_proto)
static const char *read_proto(const char * s, size_t * len, int * transport_proto)
{
const char * p;
const char * ugh;
@ -1405,8 +1398,7 @@ read_proto(const char * s, size_t * len, int * transport_proto)
* searching for each is sequential. If this becomes a problem, faster
* searches could be implemented (hash or radix tree, for example).
*/
void
scan_proc_shunts(void)
void scan_proc_shunts(void)
{
static const char procname[] = "/proc/net/ipsec_eroute";
FILE *f;
@ -1645,9 +1637,8 @@ scan_proc_shunts(void)
}
}
static bool
del_spi(ipsec_spi_t spi, int proto
, const ip_address *src, const ip_address *dest)
static bool del_spi(ipsec_spi_t spi, int proto,
const ip_address *src, const ip_address *dest)
{
char text_said[SATOT_BUF];
struct kernel_sa sa;
@ -1670,8 +1661,7 @@ del_spi(ipsec_spi_t spi, int proto
* ipsec-0.5.
*/
static bool
setup_half_ipsec_sa(struct state *st, bool inbound)
static bool setup_half_ipsec_sa(struct state *st, bool inbound)
{
/* Build an inbound or outbound SA */
@ -2122,8 +2112,7 @@ fail:
/* teardown_ipsec_sa is a canibalized version of setup_ipsec_sa */
static bool
teardown_half_ipsec_sa(struct state *st, bool inbound)
static bool teardown_half_ipsec_sa(struct state *st, bool inbound)
{
/* We need to delete AH, ESP, and IP in IP SPIs.
* But if there is more than one, they have been grouped
@ -2218,8 +2207,7 @@ teardown_half_ipsec_sa(struct state *st, bool inbound)
/*
* get information about a given sa
*/
bool
get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
{
char text_said[SATOT_BUF];
struct kernel_sa sa;
@ -2290,8 +2278,7 @@ const struct kernel_ops *kernel_ops;
#endif /* KLIPS */
void
init_kernel(void)
void init_kernel(void)
{
#ifdef KLIPS
@ -2343,8 +2330,7 @@ init_kernel(void)
* The Responder will subsequently use install_ipsec_sa for the outbound.
* The Initiator uses install_ipsec_sa to install both at once.
*/
bool
install_inbound_ipsec_sa(struct state *st)
bool install_inbound_ipsec_sa(struct state *st)
{
struct connection *const c = st->st_connection;
@ -2405,10 +2391,9 @@ install_inbound_ipsec_sa(struct state *st)
* Any SA Group must have already been created.
* On failure, steps will be unwound.
*/
bool
route_and_eroute(struct connection *c USED_BY_KLIPS
, struct spd_route *sr USED_BY_KLIPS
, struct state *st USED_BY_KLIPS)
bool route_and_eroute(struct connection *c USED_BY_KLIPS,
struct spd_route *sr USED_BY_KLIPS,
struct state *st USED_BY_KLIPS)
{
#ifdef KLIPS
struct spd_route *esr;
@ -2688,8 +2673,7 @@ route_and_eroute(struct connection *c USED_BY_KLIPS
#endif /* !KLIPS */
}
bool
install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
bool install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
{
#ifdef KLIPS
struct spd_route *sr;
@ -2764,8 +2748,8 @@ install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
* we may not succeed, but we bull ahead anyway because
* we cannot do anything better by recognizing failure
*/
void
delete_ipsec_sa(struct state *st USED_BY_KLIPS, bool inbound_only USED_BY_KLIPS)
void delete_ipsec_sa(struct state *st USED_BY_KLIPS,
bool inbound_only USED_BY_KLIPS)
{
#ifdef KLIPS
if (!inbound_only)
@ -2888,8 +2872,7 @@ bool update_ipsec_sa (struct state *st USED_BY_KLIPS)
* If FALSE, DPD is not necessary. We also return TRUE for errors, as they
* could mean that the SA is broken and needs to be replace anyway.
*/
bool
was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
bool was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
{
static const char procname[] = "/proc/net/ipsec_spi";
FILE *f;

View File

@ -24,9 +24,11 @@
#include <freeswan.h>
#include <ipsec_policy.h>
#include <library.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <asn1/oid.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
@ -34,7 +36,6 @@
#include "x509.h"
#include "crl.h"
#include "ca.h"
#include "rnd.h"
#include "certs.h"
#include "smartcard.h"
#include "whack.h"
@ -884,10 +885,14 @@ static chunk_t build_requestor_name(void)
*/
static chunk_t build_nonce_extension(ocsp_location_t *location)
{
rng_t *rng;
/* generate a random nonce */
location->nonce.ptr = malloc(NONCE_LENGTH),
location->nonce.len = NONCE_LENGTH;
get_rnd_bytes(location->nonce.ptr, NONCE_LENGTH);
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
rng->get_bytes(rng, location->nonce.len, location->nonce.ptr);
rng->destroy(rng);
return asn1_wrap(ASN1_SEQUENCE, "cm"
, ASN1_nonce_oid

View File

@ -21,9 +21,11 @@
#include <freeswan.h>
#include <libsha2/sha2.h>
#include <library.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <asn1/oid.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
@ -33,7 +35,6 @@
#include "md2.h"
#include "md5.h"
#include "sha1.h"
#include "rnd.h"
const struct fld RSA_private_field[] =
{
@ -430,6 +431,7 @@ chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
u_char *pos = padded;
int padding = key->k - in.len - 3;
int i;
rng_t *rng;
if (padding < 8 || key->k > RSA_MAX_OCTETS)
return chunk_empty;
@ -439,15 +441,17 @@ chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
*pos++ = 0x02;
/* pad with pseudo random bytes unequal to zero */
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
for (i = 0; i < padding; i++)
{
get_rnd_bytes(pos, padding);
rng->get_bytes(rng, padding, pos);
while (!*pos)
{
get_rnd_bytes(pos, 1);
rng->get_bytes(rng, 1, pos);
}
pos++;
}
rng->destroy(rng);
/* append the padding terminator */
*pos++ = 0x00;

View File

@ -20,9 +20,11 @@
#include <freeswan.h>
#include <library.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <asn1/oid.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
@ -30,7 +32,6 @@
#include "x509.h"
#include "certs.h"
#include "pkcs7.h"
#include "rnd.h"
const contentInfo_t empty_contentInfo = {
OID_UNKNOWN , /* type */
@ -744,6 +745,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int ciph
chunk_t out;
chunk_t cipher_oid;
rng_t *rng;
u_int total_keys, i;
size_t padding = pad_up(data.len, DES_CBC_BLOCK_SIZE);
@ -789,16 +791,19 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int ciph
)
/* generate a strong random key for DES/3DES */
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
des_check_key_save = des_check_key;
des_check_key = TRUE;
for (i = 0; i < total_keys;i++)
{
for (;;)
{
get_rnd_bytes((char*)key[i], DES_CBC_BLOCK_SIZE);
rng->get_bytes(rng, DES_CBC_BLOCK_SIZE, (char*)key[i]);
des_set_odd_parity(&key[i]);
if (!des_set_key(&key[i], ks[i]))
{
break;
}
plog("weak DES key discarded - we try again");
}
DBG(DBG_PRIVATE,
@ -808,11 +813,12 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int ciph
des_check_key = des_check_key_save;
/* generate an iv for DES/3DES CBC */
get_rnd_bytes(des_iv, DES_CBC_BLOCK_SIZE);
rng->get_bytes(rng, DES_CBC_BLOCK_SIZE, des_iv);
memcpy(iv.ptr, des_iv, DES_CBC_BLOCK_SIZE);
DBG(DBG_RAW,
DBG_dump_chunk("DES IV :", iv)
)
rng->destroy(rng);
/* encryption using specified cipher */
switch (cipher)

View File

@ -60,7 +60,6 @@
#include "keys.h"
#include "adns.h" /* needs <resolv.h> */
#include "dnskey.h" /* needs keys.h and adns.h */
#include "rnd.h"
#include "state.h"
#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "ocsp.h"
@ -73,6 +72,7 @@
#include "nat_traversal.h"
#include "virtual.h"
#include "timer.h"
#include "vendor.h"
static void usage(const char *mess)
{
@ -634,9 +634,8 @@ int main(int argc, char **argv)
init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
init_virtual_ip(virtual_private);
scx_init(pkcs11_module_path, pkcs11_init_args); /* load and initialize PKCS #11 module */
xauth_init(); /* load and initialize XAUTH module */
init_rnd_pool();
scx_init(pkcs11_module_path, pkcs11_init_args);
xauth_init();
init_secret();
init_states();
init_crypto();

View File

@ -1,593 +0,0 @@
/* primegen.c - prime number generator
* 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
*
* ***********************************************************************
* The algorithm used to generate practically save primes is due to
* Lim and Lee as described in the CRYPTO '97 proceedings (ISBN3540633847)
* page 260.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef PLUTO
#include <gmp.h>
#include <freeswan.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "rnd.h"
#include "gcryptfix.h"
#else /*! PLUTO */
/* #include <assert.h> */
/* #include <config.h> */
/* #include "util.h" */
/* #include "mpi.h" */
/* #include "cipher.h" */
#endif /* !PLUTO */
static int no_of_small_prime_numbers;
static MPI gen_prime( unsigned nbits, int mode, int randomlevel );
static int check_prime( MPI prime, MPI val_2 );
static int is_prime( MPI n, unsigned steps, int *count );
static void m_out_of_n( char *array, int m, int n );
static void
progress( int c )
{
fputc( c, stderr );
}
/****************
* Generate a prime number (stored in secure memory)
*/
MPI
generate_secret_prime( unsigned nbits )
{
MPI prime;
prime = gen_prime( nbits, 1, 2 );
progress('\n');
return prime;
}
MPI
generate_public_prime( unsigned nbits )
{
MPI prime;
prime = gen_prime( nbits, 0, 2 );
progress('\n');
return prime;
}
/****************
* We do not need to use the strongest RNG because we gain no extra
* security from it - The prime number is public and we could also
* offer the factors for those who are willing to check that it is
* indeed a strong prime.
*
* mode 0: Standard
* 1: Make sure that at least one factor is of size qbits.
*/
MPI
generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
MPI g, MPI **ret_factors )
{
int n; /* number of factors */
int m; /* number of primes in pool */
unsigned fbits; /* length of prime factors */
MPI *factors; /* current factors */
MPI *pool; /* pool of primes */
MPI q; /* first prime factor (variable)*/
MPI prime; /* prime test value */
MPI q_factor; /* used for mode 1 */
byte *perms = NULL;
int i, j;
int count1, count2;
unsigned nprime;
unsigned req_qbits = qbits; /* the requested q bits size */
MPI val_2 = mpi_alloc_set_ui( 2 );
/* find number of needed prime factors */
for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
;
n--;
if( !n || (mode==1 && n < 2) )
log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
if( mode == 1 ) {
n--;
fbits = (pbits - 2*req_qbits -1) / n;
qbits = pbits - req_qbits - n*fbits;
}
else {
fbits = (pbits - req_qbits -1) / n;
qbits = pbits - n*fbits;
}
if( DBG_CIPHER )
log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
pbits, req_qbits, qbits, fbits, n );
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
q = gen_prime( qbits, 0, 1 );
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
/* allocate an array to hold the factors + 2 for later usage */
#ifdef PLUTO
m_alloc_ptrs_clear(factors, n+2);
#else
factors = m_alloc_clear( (n+2) * sizeof *factors );
#endif
/* make a pool of 3n+5 primes (this is an arbitrary value) */
m = n*3+5;
if( mode == 1 )
m += 5; /* need some more for DSA */
if( m < 25 )
m = 25;
#ifdef PLUTO
m_alloc_ptrs_clear(pool, m);
#else
pool = m_alloc_clear( m * sizeof *pool );
#endif
/* permutate over the pool of primes */
count1=count2=0;
do {
next_try:
if( !perms ) {
/* allocate new primes */
for(i=0; i < m; i++ ) {
mpi_free(pool[i]);
pool[i] = NULL;
}
/* init m_out_of_n() */
#ifdef PLUTO
perms = malloc(m);
#else
perms = m_alloc_clear( m );
#endif
for(i=0; i < n; i++ ) {
perms[i] = 1;
pool[i] = gen_prime( fbits, 0, 1 );
factors[i] = pool[i];
}
}
else {
m_out_of_n( perms, n, m );
for(i=j=0; i < m && j < n ; i++ )
if( perms[i] ) {
if( !pool[i] )
pool[i] = gen_prime( fbits, 0, 1 );
factors[j++] = pool[i];
}
if( i == n ) {
m_free(perms); perms = NULL;
progress('!');
goto next_try; /* allocate new primes */
}
}
mpi_set( prime, q );
mpi_mul_ui( prime, prime, 2 );
if( mode == 1 )
mpi_mul( prime, prime, q_factor );
for(i=0; i < n; i++ )
mpi_mul( prime, prime, factors[i] );
mpi_add_ui( prime, prime, 1 );
nprime = mpi_get_nbits(prime);
if( nprime < pbits ) {
if( ++count1 > 20 ) {
count1 = 0;
qbits++;
progress('>');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
}
else
count1 = 0;
if( nprime > pbits ) {
if( ++count2 > 20 ) {
count2 = 0;
qbits--;
progress('<');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
}
else
count2 = 0;
} while( !(nprime == pbits && check_prime( prime, val_2 )) );
if( DBG_CIPHER ) {
progress('\n');
log_mpidump( "prime : ", prime );
log_mpidump( "factor q: ", q );
if( mode == 1 )
log_mpidump( "factor q0: ", q_factor );
for(i=0; i < n; i++ )
log_mpidump( "factor pi: ", factors[i] );
log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
if( mode == 1 )
fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
for(i=0; i < n; i++ )
fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
progress('\n');
}
if( ret_factors ) { /* caller wants the factors */
#ifdef PLUTO
m_alloc_ptrs_clear(*ret_factors, n+2);
#else
*ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
#endif
if( mode == 1 ) {
i = 0;
(*ret_factors)[i++] = mpi_copy( q_factor );
for(; i <= n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
else {
for(; i < n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
}
if( g ) { /* create a generator (start with 3)*/
MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
if( mode == 1 )
BUG(); /* not yet implemented */
factors[n] = q;
factors[n+1] = mpi_alloc_set_ui(2);
mpi_sub_ui( pmin1, prime, 1 );
mpi_set_ui(g,2);
do {
mpi_add_ui(g, g, 1);
if( DBG_CIPHER ) {
#ifdef PLUTO
log_mpidump("checking g: ", g);
#else
log_debug("checking g: ");
mpi_print( stderr, g, 1 );
#endif
}
else
progress('^');
for(i=0; i < n+2; i++ ) {
/*fputc('~', stderr);*/
mpi_fdiv_q(tmp, pmin1, factors[i] );
/* (no mpi_pow(), but it is okay to use this with mod prime) */
mpi_powm(b, g, tmp, prime );
if( !mpi_cmp_ui(b, 1) )
break;
}
if( DBG_CIPHER )
progress('\n');
} while( i < n+2 );
mpi_free(factors[n+1]);
mpi_free(tmp);
mpi_free(b);
mpi_free(pmin1);
}
if( !DBG_CIPHER )
progress('\n');
m_free( factors ); /* (factors are shallow copies) */
for(i=0; i < m; i++ )
mpi_free( pool[i] );
m_free( pool );
m_free(perms);
mpi_free(val_2);
return prime;
}
static MPI
gen_prime( unsigned nbits, int secret, int randomlevel )
{
unsigned nlimbs;
MPI prime, ptest, pminus1, val_2, val_3, result;
int i;
unsigned x, step;
unsigned count1, count2;
int *mods;
if( 0 && DBG_CIPHER )
log_debug("generate a prime of %u bits ", nbits );
if( !no_of_small_prime_numbers ) {
for(i=0; small_prime_numbers[i]; i++ )
no_of_small_prime_numbers++;
}
mods = m_alloc( 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 );
val_3 = mpi_alloc_set_ui( 3);
prime = secret? mpi_alloc_secure( nlimbs ): mpi_alloc( nlimbs );
result = mpi_alloc_like( prime );
pminus1= mpi_alloc_like( prime );
ptest = mpi_alloc_like( prime );
count1 = count2 = 0;
for(;;) { /* try forvever */
int dotcount=0;
/* generate a random number */
{ char *p = get_random_bits( nbits, randomlevel, secret );
mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
m_free(p);
}
/* set high order bit to 1, set low order bit to 1 */
mpi_set_highbit( prime, nbits-1 );
mpi_set_bit( prime, 0 );
/* calculate all remainders */
for(i=0; (x = small_prime_numbers[i]); i++ )
mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
/* now try some primes starting with prime */
for(step=0; step < 20000; step += 2 ) {
/* check against all the small primes we have in mods */
count1++;
for(i=0; (x = small_prime_numbers[i]); i++ ) {
while( mods[i] + step >= x )
mods[i] -= x;
if( !(mods[i] + step) )
break;
}
if( x )
continue; /* found a multiple of an already known prime */
mpi_add_ui( ptest, prime, step );
/* do a faster Fermat test */
count2++;
mpi_sub_ui( pminus1, ptest, 1);
mpi_powm( result, val_2, pminus1, ptest );
if( !mpi_cmp_ui( result, 1 ) ) { /* not composite */
/* perform stronger tests */
if( is_prime(ptest, 5, &count2 ) ) {
if( !mpi_test_bit( ptest, nbits-1 ) ) {
progress('\n');
log_debug("overflow in prime generation\n");
break; /* step loop, continue with a new prime */
}
mpi_free(val_2);
mpi_free(val_3);
mpi_free(result);
mpi_free(pminus1);
mpi_free(prime);
m_free(mods);
return ptest;
}
}
if( ++dotcount == 10 ) {
progress('.');
dotcount = 0;
}
}
progress(':'); /* restart with a new random value */
}
}
/****************
* Returns: true if this may be a prime
*/
static int
check_prime( MPI prime, MPI val_2 )
{
int i;
unsigned x;
int count=0;
/* check against small primes */
for(i=0; (x = small_prime_numbers[i]); i++ ) {
if( mpi_divisible_ui( prime, x ) )
return 0;
}
/* a quick fermat test */
{
MPI result = mpi_alloc_like( prime );
MPI pminus1 = mpi_alloc_like( prime );
mpi_sub_ui( pminus1, prime, 1);
mpi_powm( result, val_2, pminus1, prime );
mpi_free( pminus1 );
if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
mpi_free( result );
progress('.');
return 0;
}
mpi_free( result );
}
/* perform stronger tests */
if( is_prime(prime, 5, &count ) )
return 1; /* is probably a prime */
progress('.');
return 0;
}
/****************
* Return true if n is probably a prime
*/
static int
is_prime( MPI n, unsigned steps, int *count )
{
MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
MPI a2 = mpi_alloc_set_ui( 2 );
MPI q;
unsigned i, j, k;
int rc = 0;
unsigned nbits = mpi_get_nbits( n );
mpi_sub_ui( nminus1, n, 1 );
/* find q and k, so that n = 1 + 2^k * q */
q = mpi_copy( nminus1 );
k = mpi_trailing_zeros( q );
mpi_tdiv_q_2exp(q, q, k);
for(i=0 ; i < steps; i++ ) {
++*count;
if( !i ) {
mpi_set_ui( x, 2 );
}
else {
/*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);
}
/* make sure that the number is smaller than the prime
* and keep the randomness of the high bit */
if( mpi_test_bit( x, nbits-2 ) ) {
mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
}
else {
mpi_set_highbit( x, nbits-2 );
mpi_clear_bit( x, nbits-2 );
}
assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
}
mpi_powm( y, x, q, n);
if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
mpi_powm(y, y, a2, n);
if( !mpi_cmp_ui( y, 1 ) )
goto leave; /* not a prime */
}
if( mpi_cmp( y, nminus1 ) )
goto leave; /* not a prime */
}
progress('+');
}
rc = 1; /* may be a prime */
leave:
mpi_free( x );
mpi_free( y );
mpi_free( z );
mpi_free( nminus1 );
mpi_free( q );
return rc;
}
static void
m_out_of_n( char *array, int m, int n )
{
int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
if( !m || m >= n )
return;
if( m == 1 ) { /* special case */
for(i=0; i < n; i++ )
if( array[i] ) {
array[i++] = 0;
if( i >= n )
i = 0;
array[i] = 1;
return;
}
BUG();
}
for(j=1; j < n; j++ ) {
if( array[n-1] == array[n-j-1] )
continue;
j1 = j;
break;
}
if( m & 1 ) { /* m is odd */
if( array[n-1] ) {
if( j1 & 1 ) {
k1 = n - j1;
k2 = k1+2;
if( k2 > n )
k2 = n;
goto leave;
}
goto scan;
}
k2 = n - j1 - 1;
if( k2 == 0 ) {
k1 = i;
k2 = n - j1;
}
else if( array[k2] && array[k2-1] )
k1 = n;
else
k1 = k2 + 1;
}
else { /* m is even */
if( !array[n-1] ) {
k1 = n - j1;
k2 = k1 + 1;
goto leave;
}
if( !(j1 & 1) ) {
k1 = n - j1;
k2 = k1+2;
if( k2 > n )
k2 = n;
goto leave;
}
scan:
jp = n - j1 - 1;
for(i=1; i <= jp; i++ ) {
i1 = jp + 2 - i;
if( array[i1-1] ) {
if( array[i1-2] ) {
k1 = i1 - 1;
k2 = n - j1;
}
else {
k1 = i1 - 1;
k2 = n + 1 - j1;
}
goto leave;
}
}
k1 = 1;
k2 = n + 1 - m;
}
leave:
array[k1-1] = !array[k1-1];
array[k2-1] = !array[k2-1];
}

View File

@ -1,122 +0,0 @@
/* smallprime.c - List of small primes
* 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
*/
#ifdef PLUTO
#include <gmp.h>
#include <freeswan.h>
#include "constants.h"
#include "defs.h"
#include "gcryptfix.h"
#else
/* #include <config.h> */
/* #include <stdio.h> */
/* #include <stdlib.h> */
/* #include "util.h" */
/* #include "types.h" */
#endif
/* Note: 2 is not included because it can be tested more easily
* by looking at bit 0. The last entry in this list is marked by a zero
*/
ushort
small_prime_numbers[] = {
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
4957, 4967, 4969, 4973, 4987, 4993, 4999,
0
};

View File

@ -26,6 +26,9 @@
#include <freeswan.h>
#include <library.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
#include "connections.h"
@ -34,7 +37,6 @@
#include "log.h"
#include "packet.h" /* so we can calculate sizeof(struct isakmp_hdr) */
#include "keys.h" /* for free_public_key */
#include "rnd.h"
#include "timer.h"
#include "whack.h"
#include "demux.h" /* needs packet.h */
@ -81,8 +83,7 @@ struct msgid_list
struct msgid_list *next;
};
bool
reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
{
struct msgid_list *p;
@ -100,20 +101,22 @@ reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
return TRUE;
}
msgid_t
generate_msgid(struct state *isakmp_sa)
msgid_t generate_msgid(struct state *isakmp_sa)
{
int timeout = 100; /* only try so hard for unique msgid */
msgid_t msgid;
rng_t *rng;
passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
for (;;)
{
get_rnd_bytes((void *) &msgid, sizeof(msgid));
rng->get_bytes(rng, sizeof(msgid), (void *) &msgid);
if (msgid != 0 && reserve_msgid(isakmp_sa, msgid))
{
break;
}
if (--timeout == 0)
{
plog("gave up looking for unique msgid; using 0x%08lx"
@ -121,6 +124,7 @@ generate_msgid(struct state *isakmp_sa)
break;
}
}
rng->destroy(rng);
return msgid;
}
@ -131,8 +135,8 @@ generate_msgid(struct state *isakmp_sa)
static struct state *statetable[STATE_TABLE_SIZE];
static struct state **
state_hash(const u_char *icookie, const u_char *rcookie, const ip_address *peer)
static struct state **state_hash(const u_char *icookie, const u_char *rcookie,
const ip_address *peer)
{
u_int i = 0, j;
const unsigned char *byte_ptr;
@ -162,8 +166,7 @@ state_hash(const u_char *icookie, const u_char *rcookie, const ip_address *peer)
* Caller must schedule an event for this object so that it doesn't leak.
* Caller must insert_state().
*/
struct state *
new_state(void)
struct state *new_state(void)
{
static const struct state blank_state; /* initialized all to zero & NULL */
static so_serial_t next_so = SOS_FIRST;
@ -181,8 +184,7 @@ new_state(void)
/*
* Initialize the state table (and mask*).
*/
void
init_states(void)
void init_states(void)
{
int i;
@ -197,8 +199,7 @@ init_states(void)
* If this turns out to be a significant CPU hog, it could be
* improved to use a hash table rather than sequential seartch.
*/
struct state *
state_with_serialno(so_serial_t sn)
struct state *state_with_serialno(so_serial_t sn)
{
if (sn >= SOS_FIRST)
{
@ -217,8 +218,7 @@ state_with_serialno(so_serial_t sn)
* at the begining of list.
* Needs cookies, connection, and msgid.
*/
void
insert_state(struct state *st)
void insert_state(struct state *st)
{
struct state **p = state_hash(st->st_icookie, st->st_rcookie
, &st->st_connection->spd.that.host_addr);
@ -244,8 +244,7 @@ insert_state(struct state *st)
/* unlink a state object from the hash table, but don't free it
*/
void
unhash_state(struct state *st)
void unhash_state(struct state *st)
{
/* unlink from forward chain */
struct state **p = st->st_hashchain_prev == NULL
@ -270,15 +269,15 @@ unhash_state(struct state *st)
/* Free the Whack socket file descriptor.
* This has the side effect of telling Whack that we're done.
*/
void
release_whack(struct state *st)
void release_whack(struct state *st)
{
close_any(st->st_whack_sock);
}
/* delete a state object */
void
delete_state(struct state *st)
/**
* Delete a state object
*/
void delete_state(struct state *st)
{
struct connection *const c = st->st_connection;
struct state *old_cur_state = cur_state == st? NULL : cur_state;
@ -372,11 +371,10 @@ delete_state(struct state *st)
free(st);
}
/*
/**
* Is a connection in use by some state?
*/
bool
states_use_connection(struct connection *c)
bool states_use_connection(struct connection *c)
{
/* are there any states still using it? */
struct state *st = NULL;
@ -390,13 +388,12 @@ states_use_connection(struct connection *c)
return FALSE;
}
/*
* delete all states that were created for a given connection.
/**
* Delete all states that were created for a given connection.
* if relations == TRUE, then also delete states that share
* the same phase 1 SA.
*/
void
delete_states_by_connection(struct connection *c, bool relations)
void delete_states_by_connection(struct connection *c, bool relations)
{
int pass;
/* this kludge avoids an n^2 algorithm */
@ -465,11 +462,11 @@ delete_states_by_connection(struct connection *c, bool relations)
c->kind = ck;
}
/* Walk through the state table, and delete each state whose phase 1 (IKE)
/**
* Walk through the state table, and delete each state whose phase 1 (IKE)
* peer is among those given.
*/
void
delete_states_by_peer(ip_address *peer)
void delete_states_by_peer(ip_address *peer)
{
char peerstr[ADDRTOT_BUF];
int i;
@ -512,8 +509,7 @@ delete_states_by_peer(ip_address *peer)
* Caller must schedule an event for this object so that it doesn't leak.
* Caller must insert_state().
*/
struct state *
duplicate_state(struct state *st)
struct state *duplicate_state(struct state *st)
{
struct state *nst;
@ -558,14 +554,11 @@ void for_each_state(void *(f)(struct state *, void *data), void *data)
}
#endif
/*
/**
* Find a state object.
*/
struct state *
find_state(const u_char *icookie
, const u_char *rcookie
, const ip_address *peer
, msgid_t /*network order*/ msgid)
struct state *find_state(const u_char *icookie, const u_char *rcookie,
const ip_address *peer, msgid_t msgid)
{
struct state *st = *state_hash(icookie, rcookie, peer);
@ -594,11 +587,11 @@ find_state(const u_char *icookie
return st;
}
/* Find the state that sent a packet
/**
* Find the state that sent a packet
* ??? this could be expensive -- it should be rate-limited to avoid DoS
*/
struct state *
find_sender(size_t packet_len, u_char *packet)
struct state *find_sender(size_t packet_len, u_char *packet)
{
int i;
struct state *st;
@ -621,11 +614,9 @@ find_sender(size_t packet_len, u_char *packet)
return NULL;
}
struct state *
find_phase2_state_to_delete(const struct state *p1st
, u_int8_t protoid
, ipsec_spi_t spi
, bool *bogus)
struct state *find_phase2_state_to_delete(const struct state *p1st,
u_int8_t protoid, ipsec_spi_t spi,
bool *bogus)
{
struct state *st;
int i;
@ -655,10 +646,10 @@ find_phase2_state_to_delete(const struct state *p1st
return NULL;
}
/* Find newest Phase 1 negotiation state object for suitable for connection c
/**
* Find newest Phase 1 negotiation state object for suitable for connection c
*/
struct state *
find_phase1_state(const struct connection *c, lset_t ok_states)
struct state *find_phase1_state(const struct connection *c, lset_t ok_states)
{
struct state
*st,
@ -676,9 +667,8 @@ find_phase1_state(const struct connection *c, lset_t ok_states)
return best;
}
void
state_eroute_usage(ip_subnet *ours, ip_subnet *his
, unsigned long count, time_t nw)
void state_eroute_usage(ip_subnet *ours, ip_subnet *his, unsigned long count,
time_t nw)
{
struct state *st;
int i;
@ -717,9 +707,8 @@ state_eroute_usage(ip_subnet *ours, ip_subnet *his
});
}
void fmt_state(bool all, struct state *st, time_t n
, char *state_buf, size_t state_buf_len
, char *state_buf2, size_t state_buf2_len)
void fmt_state(bool all, struct state *st, time_t n, char *state_buf,
size_t state_buf_len, char *state_buf2, size_t state_buf2_len)
{
/* what the heck is interesting about a state? */
const struct connection *c = st->st_connection;
@ -835,8 +824,7 @@ void fmt_state(bool all, struct state *st, time_t n
* isakmp_sa (XXX probably wrong)
*
*/
static int
state_compare(const void *a, const void *b)
static int state_compare(const void *a, const void *b)
{
const struct state *sap = *(const struct state *const *)a;
struct connection *ca = sap->st_connection;
@ -848,8 +836,7 @@ state_compare(const void *a, const void *b)
return connection_compare(ca, cb);
}
void
show_states_status(bool all, const char *name)
void show_states_status(bool all, const char *name)
{
time_t n = now();
int i;
@ -919,8 +906,7 @@ show_states_status(bool all, const char *name)
* If we can't find one easily, choose 0 (a bad SPI,
* no matter what order) indicating failure.
*/
void
find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
{
int tries = 0;
cpi_t base = *latest_cpi;
@ -972,16 +958,16 @@ startover:
* If we can't find one easily, return 0 (a bad SPI,
* no matter what order) indicating failure.
*/
ipsec_spi_t
uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
{
int tries = 0;
int i;
rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
startover:
/* network order makes first two bytes our target */
get_rnd_bytes((u_char *)&cpi, 2);
rng->get_bytes(rng, 2, (u_char *)&cpi);
/* Make sure that the result is unique.
* Hard work. If there is no unique value, we'll loop forever!
@ -998,11 +984,15 @@ startover:
&& cpi == s->st_ipcomp.attrs.spi)
{
if (++tries == 20)
{
rng->destroy(rng);
return 0; /* FAILURE */
}
goto startover;
}
}
}
rng->destroy(rng);
return cpi;
}

View File

@ -24,6 +24,9 @@
#include <freeswan.h>
#include <library.h>
#include <crypto/rngs/rng.h>
#include "constants.h"
#include "defs.h"
#include "connections.h"
@ -33,14 +36,14 @@
#include "kernel.h"
#include "server.h"
#include "log.h"
#include "rnd.h"
#include "timer.h"
#include "whack.h"
#include "nat_traversal.h"
/* monotonic version of time(3) */
time_t
now(void)
/**
* monotonic version of time(3)
*/
time_t now(void)
{
static time_t delta = 0
, last_time = 0;
@ -64,11 +67,10 @@ now(void)
static struct event *evlist = (struct event *) NULL;
/*
/**
* This routine places an event in the event list.
*/
void
event_schedule(enum event_type type, time_t tm, struct state *st)
void event_schedule(enum event_type type, time_t tm, struct state *st)
{
struct event *ev = malloc_thing(struct event);
@ -133,11 +135,24 @@ event_schedule(enum event_type type, time_t tm, struct state *st)
}
}
/*
/**
* Generate the secret value for responder cookies, and
* schedule an event for refresh.
*/
void init_secret(void)
{
rng_t *rng;
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
rng->get_bytes(rng, sizeof(secret_of_the_day), secret_of_the_day);
rng->destroy(rng);
event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
}
/**
* Handle the first event on the list.
*/
void
handle_timer_event(void)
void handle_timer_event(void)
{
time_t tm;
struct event *ev = evlist;
@ -434,12 +449,11 @@ handle_timer_event(void)
reset_cur_state();
}
/*
/**
* Return the time until the next event in the queue
* expires (never negative), or -1 if no jobs in queue.
*/
long
next_event(void)
long next_event(void)
{
time_t tm;
@ -465,11 +479,10 @@ next_event(void)
return evlist->ev_time - tm;
}
/*
/**
* Delete an event.
*/
void
delete_event(struct state *st)
void delete_event(struct state *st)
{
if (st->st_event != (struct event *) NULL)
{
@ -500,11 +513,10 @@ delete_event(struct state *st)
}
}
/*
/**
* Delete a DPD event.
*/
void
delete_dpd_event(struct state *st)
void delete_dpd_event(struct state *st)
{
if (st->st_dpd_event != (struct event *) NULL)
{
@ -529,11 +541,10 @@ delete_dpd_event(struct state *st)
}
}
/*
/**
* Free remaining events
*/
void
free_events(void)
void free_events(void)
{
struct event *ev_tmp, *ev;

View File

@ -31,3 +31,4 @@ extern void delete_event(struct state *st);
extern void delete_dpd_event(struct state *st);
extern void daily_log_event(void);
extern void free_events(void);
extern void init_secret(void);

View File

@ -90,7 +90,7 @@ struct vid_struct {
unsigned short flags;
const char *data;
const char *descr;
const char *vid;
char *vid;
u_int vid_len;
};

View File

@ -20,6 +20,7 @@ AM_CFLAGS = \
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
-DPLUGINS=\""${pluto_plugins}\"" \
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
-DNO_CREDENTIAL_FACTORY \
-DDEBUG -DNO_PLUTO
LIBSTRONGSWANBUILDDIR=$(top_builddir)/src/libstrongswan
@ -28,7 +29,7 @@ LIBCRYPTOBUILDDIR=$(top_builddir)/src/libcrypto
scepclient_LDADD = \
ca.o crl.o certs.o constants.o defs.o fetch.o id.o keys.o lex.o \
md2.o md5.o mp_defs.o ocsp.o pem.o pgp.o pkcs1.o pkcs7.o rnd.o sha1.o \
md2.o md5.o mp_defs.o ocsp.o pem.o pgp.o pkcs1.o pkcs7.o sha1.o \
smartcard.o x509.o \
$(LIBSTRONGSWANBUILDDIR)/libstrongswan.la \
$(LIBFREESWANBUILDDIR)/libfreeswan.a \
@ -94,9 +95,6 @@ pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
pkcs7.o : $(PLUTODIR)/pkcs7.c $(PLUTODIR)/pkcs7.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
$(COMPILE) $(INCLUDES) -c -o $@ $<

View File

@ -30,6 +30,9 @@
#include <freeswan.h>
#include <library.h>
#include <crypto/rngs/rng.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/mp_defs.h"
@ -58,45 +61,6 @@
* @return TRUE, if succeeded, FALSE otherwise
*/
static bool
get_true_random_bytes(size_t nbytes, char *buf)
{
size_t ndone;
size_t got;
char *device = DEV_RANDOM;
int dev = open(DEV_RANDOM, 0);
if (dev < 0)
{
fprintf(stderr, "could not open random device %s", device);
return FALSE;
}
DBG(DBG_CONTROL,
DBG_log("getting %d bytes from %s...", (int) nbytes, device)
)
ndone = 0;
while (ndone < nbytes)
{
got = read(dev, buf + ndone, nbytes - ndone);
if (got < 0)
{
fprintf(stderr, "read error on %s", device);
return FALSE;
}
if (got == 0)
{
fprintf(stderr, "eof on %s", device);
return FALSE;
}
ndone += got;
}
close(dev);
return TRUE;
}
/**
* @brief initialize an mpz_t to a random number, specified bit count
*
@ -110,17 +74,20 @@ get_true_random_bytes(size_t nbytes, char *buf)
* @param[in] nbits length of var in bits (known to be a multiple of BITS_PER_BYTE)
* @return TRUE on success, FALSE otherwise
*/
static bool
init_random(mpz_t var, int nbits)
static bool init_random(mpz_t var, int nbits)
{
size_t nbytes = (size_t)(nbits/BITS_PER_BYTE);
char random_buf[RSA_MAX_OCTETS/2];
rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
assert(nbytes <= sizeof(random_buf));
if (!get_true_random_bytes(nbytes, random_buf))
if (!rng)
{
return FALSE;
}
assert(nbytes <= sizeof(random_buf));
rng->get_bytes(rng, nbytes, random_buf);
rng->destroy(rng);
random_buf[0] |= 01 << (BITS_PER_BYTE-1); /* force high bit on */
random_buf[nbytes-1] |= 01; /* force low bit on */
n_to_mpz(var, random_buf, nbytes);
@ -138,8 +105,7 @@ init_random(mpz_t var, int nbits)
* @param[in] eval E-Value, 0 means don't bother w. tweak
* @return 1 on success, 0 otherwise
*/
static bool
init_prime(mpz_t var, int nbits, int eval)
static bool init_prime(mpz_t var, int nbits, int eval)
{
unsigned long tries;
size_t len;
@ -194,8 +160,7 @@ init_prime(mpz_t var, int nbits, int eval)
* @param[in] nbits size of rsa key in bits
* @return RSA_public_key_t containing the generated RSA key
*/
err_t
generate_rsa_private_key(int nbits, RSA_private_key_t *key)
err_t generate_rsa_private_key(int nbits, RSA_private_key_t *key)
{
mpz_t p, q, n, e, d, exp1, exp2, coeff;
mpz_t m, q1, t; /* temporary variables*/

View File

@ -29,10 +29,10 @@
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <asn1/oid.h>
#include <crypto/rngs/rng.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/rnd.h"
#include "../pluto/pkcs1.h"
#include "../pluto/fetch.h"
#include "../pluto/log.h"
@ -355,8 +355,11 @@ chunk_t scep_senderNonce_attribute(void)
const size_t nonce_len = 16;
u_char nonce_buf[nonce_len];
chunk_t senderNonce = { nonce_buf, nonce_len };
rng_t *rng;
get_rnd_bytes(nonce_buf, nonce_len);
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
rng->get_bytes(rng, nonce_len, nonce_buf);
rng->destroy(rng);
return asn1_wrap(ASN1_SEQUENCE, "cm"
, ASN1_senderNonce_oid

View File

@ -35,6 +35,7 @@
#include <gmp.h>
#include <freeswan.h>
#include <library.h>
#include <debug.h>
#include <asn1/asn1.h>
@ -48,7 +49,6 @@
#include "../pluto/pkcs1.h"
#include "../pluto/pkcs7.h"
#include "../pluto/certs.h"
#include "../pluto/rnd.h"
#include "rsakey.h"
#include "pkcs10.h"
@ -747,9 +747,6 @@ int main(int argc, char **argv)
lib->settings->get_str(lib->settings, "scepclient.load", PLUGINS));
print_plugins();
init_rnd_pool();
init_fetch();
if ((filetype_out == 0) && (!request_ca_certificate))
{
usage ("--out filetype required");