diff --git a/CHANGES b/CHANGES index b43618952359ec730aeb9906a58aad83d1c37e07..661876126983991ccd9628c668ef264c79162c19 100644 --- a/CHANGES +++ b/CHANGES @@ -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 diff --git a/config b/config index 50d9740762b45921e167ee4a38ed2daa4627fb82..578d08b9de344150f352470e9b73c299e6d886ef 100755 --- a/config +++ b/config @@ -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 diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index 8593ed0f392448be4fa96f8c4d7f0cba156fe4f4..0c11601675493bef66c3f88a6bf1c7c88f642b5c 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -59,6 +59,12 @@ #include #include "cryptlib.h" #include "bn_lcl.h" +#ifdef ATALLA +# include +# include +# include +# include +#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);