Commit bd03b99b authored by Ben Laurie's avatar Ben Laurie
Browse files

Add support for Compaq Atalla crypto accelerator.

parent 8691ff97
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@

 Changes between 0.9.4 and 0.9.5  [xx XXX 2000]

  *) Add support for the Compaq Atalla crypto accelerator. If it is installed,
     the support is automatically enabled. The resulting binaries will
     autodetect the card and use it if present.
     [Ben Laurie and Compaq Inc.]

  *) Work around for Netscape hang bug. This sends certificate request
     and server done in one record. Since this is perfectly legal in the
     SSL/TLS protocol it isn't a "bug" option and is on by default. See
+6 −0
Original line number Diff line number Diff line
@@ -458,6 +458,12 @@ case "$GUESSOS" in
  *) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
esac

# See whether we can compile Atalla support
if [ -f /usr/include/atasi.h ]
then
  options="$options -DATALLA"
fi

# gcc < 2.8 does not support -mcpu=ultrasparc
if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ]
then
+190 −0
Original line number Diff line number Diff line
@@ -59,6 +59,12 @@
#include <stdio.h>
#include "cryptlib.h"
#include "bn_lcl.h"
#ifdef ATALLA
# include <alloca.h>
# include <atasi.h>
# include <assert.h>
# include <dlfcn.h>
#endif

#define TABLE_SIZE	16

@@ -157,6 +163,173 @@ err:
	return(ret);
	}

#ifdef ATALLA

/*
 * This routine will dynamically check for the existance of an Atalla AXL-200
 * SSL accelerator module.  If one is found, the variable
 * asi_accelerator_present is set to 1 and the function pointers
 * ptr_ASI_xxxxxx above will be initialized to corresponding ASI API calls.
 */
typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
					    unsigned int *ret_buf);
typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
				     unsigned char *output,
				     unsigned char *input,
				     unsigned int modulus_len);

static tfnASI_GetHardwareConfig *ptr_ASI_GetHardwareConfig;
static tfnASI_RSAPrivateKeyOpFn *ptr_ASI_RSAPrivateKeyOpFn;
static tfnASI_GetPerformanceStatistics *ptr_ASI_GetPerformanceStatistics;
static int asi_accelerator_present;
static int tried_atalla;

void atalla_initialize_accelerator_handle(void)
	{
	void *dl_handle;
	int status;
	unsigned int config_buf[1024]; 
	static int tested;

	if(tested)
		return;

	tested=1;

	bzero((void *)config_buf, 1024);

	/*
	 * Check to see if the library is present on the system
	 */
	dl_handle = dlopen("atasi.so", RTLD_NOW);
	if (dl_handle == (void *) NULL)
		{
/*		printf("atasi.so library is not present on the system\n");
		printf("No HW acceleration available\n");*/
		return;
	        }

	/*
	 * The library is present.  Now we'll check to insure that the
	 * LDM is up and running. First we'll get the address of the
	 * function in the atasi library that we need to see if the
	 * LDM is operating.
	 */

	ptr_ASI_GetHardwareConfig =
	  (tfnASI_GetHardwareConfig *)dlsym(dl_handle,"ASI_GetHardwareConfig");

	if (ptr_ASI_GetHardwareConfig)
		{
		/*
		 * We found the call, now we'll get our config
		 * status.  If we get a non 0 result, the LDM is not
		 * running and we cannot use the Atalla ASI *
		 * library.
		 */
		status = (*ptr_ASI_GetHardwareConfig)(0L, config_buf);
		if (status != 0)
			{
			printf("atasi.so library is present but not initialized\n");
			printf("No HW acceleration available\n");
			return;
			}    
	        }
	else
		{
/*		printf("We found the library, but not the function. Very Strange!\n");*/
		return ;
	      	}

	/* 
	 * It looks like we have acceleration capabilities.  Load up the
	 * pointers to our ASI API calls.
	 */
	ptr_ASI_RSAPrivateKeyOpFn=
	  (tfnASI_RSAPrivateKeyOpFn *)dlsym(dl_handle, "ASI_RSAPrivateKeyOpFn");
	if (ptr_ASI_RSAPrivateKeyOpFn == NULL)
		{
/*		printf("We found the library, but no RSA function. Very Strange!\n");*/
		return;
	        }

	ptr_ASI_GetPerformanceStatistics =
	  (tfnASI_GetPerformanceStatistics *)dlsym(dl_handle, "ASI_GetPerformanceStatistics");
	if (ptr_ASI_GetPerformanceStatistics == NULL)
		{
/*		printf("We found the library, but no stat function. Very Strange!\n");*/
		return;
	      }

	/*
	 * Indicate that acceleration is available
	 */
	asi_accelerator_present = 1;

/*	printf("This system has acceleration!\n");*/

	return;
	}

/* make sure this only gets called once when bn_mod_exp calls bn_mod_exp_mont */
int BN_mod_exp_atalla(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m)
	{
	unsigned char *abin;
	unsigned char *pbin;
	unsigned char *mbin;
	unsigned char *rbin;
	int an,pn,mn,ret;
	RSAPrivateKey keydata;

	atalla_initialize_accelerator_handle();
	if(!asi_accelerator_present)
		return 0;


/* We should be able to run without size testing */
# define ASIZE	128
	an=BN_num_bytes(a);
	pn=BN_num_bytes(p);
	mn=BN_num_bytes(m);

	if(an <= ASIZE && pn <= ASIZE && mn <= ASIZE)
	    {
	    int size=mn;

	    assert(an <= mn);
	    abin=alloca(size);
	    memset(abin,'\0',mn);
	    BN_bn2bin(a,abin+size-an);

	    pbin=alloca(pn);
	    BN_bn2bin(p,pbin);

	    mbin=alloca(size);
	    memset(mbin,'\0',mn);
	    BN_bn2bin(m,mbin+size-mn);

	    rbin=alloca(size);

	    memset(&keydata,'\0',sizeof keydata);
	    keydata.privateExponent.data=pbin;
	    keydata.privateExponent.len=pn;
	    keydata.modulus.data=mbin;
	    keydata.modulus.len=size;

	    ret=(*ptr_ASI_RSAPrivateKeyOpFn)(&keydata,rbin,abin,keydata.modulus.len);
/*fprintf(stderr,"!%s\n",BN_bn2hex(a));*/
	    if(!ret)
	        {
		BN_bin2bn(rbin,keydata.modulus.len,r);
/*fprintf(stderr,"?%s\n",BN_bn2hex(r));*/
		return 1;
	        }
	    }
	return 0;
        }
#endif /* def ATALLA */

int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
	       BN_CTX *ctx)
	{
@@ -166,6 +339,13 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
	bn_check_top(p);
	bn_check_top(m);

#ifdef ATALLA
	if(BN_mod_exp_atalla(r,a,p,m))
	    return 1;
/* If it fails, try the other methods (but don't try atalla again) */
	tried_atalla=1;
#endif

#ifdef MONT_MUL_MOD
	/* I have finally been able to take out this pre-condition of
	 * the top bit being set.  It was caused by an error in BN_div
@@ -183,6 +363,10 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
#endif

#ifdef ATALLA
	tried_atalla=0;
#endif

	return(ret);
	}

@@ -318,6 +502,12 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
	bn_check_top(p);
	bn_check_top(m);

#ifdef ATALLA
	if(!tried_atalla && BN_mod_exp_atalla(rr,a,p,m))
	    return 1;
/* If it fails, try the other methods */
#endif

	if (!(m->d[0] & 1))
		{
		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);