/* DSA sign and verify */ static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa) { int ret=0; char *hptr=NULL; DSA_SIG *psign=NULL; char msg[64]="ENGINE_dsa_do_sign"; if (!p_surewarehk_Dsa_Sign) { SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED); goto err; } /* extract ref to private key */ else if (!(hptr=(char*)DSA_get_ex_data(dsa, dsaHndidx))) { SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS); goto err; } else { if((psign = DSA_SIG_new()) == NULL) { SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE); goto err; } psign->r=BN_new(); psign->s=BN_new(); bn_expand2(psign->r, 20/sizeof(BN_ULONG)); bn_expand2(psign->s, 20/sizeof(BN_ULONG)); if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) || !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG)) goto err; ret=p_surewarehk_Dsa_Sign(msg,flen,from, (unsigned long *)psign->r->d, (unsigned long *)psign->s->d, hptr); surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret); } psign->r->top=20/sizeof(BN_ULONG); bn_fix_top(psign->r); psign->s->top=20/sizeof(BN_ULONG); bn_fix_top(psign->s); err: if (psign) { DSA_SIG_free(psign); psign=NULL; } return psign; }
int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) { int i,nw,lb,rb; BN_ULONG *t,*f; BN_ULONG l; r->neg=a->neg; if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0); nw=n/BN_BITS2; lb=n%BN_BITS2; rb=BN_BITS2-lb; f=a->d; t=r->d; t[a->top+nw]=0; if (lb == 0) for (i=a->top-1; i>=0; i--) t[nw+i]=f[i]; else for (i=a->top-1; i>=0; i--) { l=f[i]; t[nw+i+1]|=(l>>rb)&BN_MASK2; t[nw+i]=(l<<lb)&BN_MASK2; } memset(t,0,nw*sizeof(t[0])); /* for (i=0; i<nw; i++) t[i]=0;*/ r->top=a->top+nw+1; bn_fix_top(r); return(1); }
static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { int ret=0; char msg[64]="ENGINE_modexp"; if (!p_surewarehk_Mod_Exp) { SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP,ENGINE_R_NOT_INITIALISED); } else { bn_expand2(r,m->top); if (r && r->dmax==m->top) { /* do it*/ ret=p_surewarehk_Mod_Exp(msg, m->top*sizeof(BN_ULONG), (unsigned long *)m->d, p->top*sizeof(BN_ULONG), (unsigned long *)p->d, a->top*sizeof(BN_ULONG), (unsigned long *)a->d, (unsigned long *)r->d); surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MODEXP,ret); if (ret==1) { /* normalise result */ r->top=m->top; bn_fix_top(r); } } } return ret; }
int BN_rshift1(BIGNUM *r, BIGNUM *a) { BN_ULONG *ap,*rp,t,c; int i; if (BN_is_zero(a)) { BN_zero(r); return(1); } if (a != r) { if (bn_wexpand(r,a->top) == NULL) return(0); r->top=a->top; r->neg=a->neg; } ap=a->d; rp=r->d; c=0; for (i=a->top-1; i>=0; i--) { t=ap[i]; rp[i]=((t>>1)&BN_MASK2)|c; c=(t&1)?BN_TBIT:0; } bn_fix_top(r); return(1); }
/* A little mod_exp */ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them directly, plus a little macro magic. We only thing we need to make sure of is that enough space is allocated. */ HWCryptoHook_MPI m_a, m_p, m_n, m_r; int to_return, ret; to_return = 0; /* expect failure */ rmsg.buf = tempbuf; rmsg.size = sizeof(tempbuf); if(!hwcrhk_context) { HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED); goto err; } /* Prepare the params */ bn_expand2(r, m->top); /* Check for error !! */ BN2MPI(m_a, a); BN2MPI(m_p, p); BN2MPI(m_n, m); MPI2BN(r, m_r); /* Perform the operation */ ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); /* Convert the response */ r->top = m_r.size / sizeof(BN_ULONG); bn_fix_top(r); if (ret < 0) { /* FIXME: When this error is returned, HWCryptoHook is telling us that falling back to software computation might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK); } else { HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; } to_return = 1; err: return to_return; }
int BN_rshift(BIGNUM *r, BIGNUM *a, int n) { int i,j,nw,lb,rb; BN_ULONG *t,*f; BN_ULONG l,tmp; nw=n/BN_BITS2; rb=n%BN_BITS2; lb=BN_BITS2-rb; if (nw > a->top || a->top == 0) { BN_zero(r); return(1); } if (r != a) { r->neg=a->neg; if (bn_wexpand(r,a->top-nw+1) == NULL) return(0); } else { if (n == 0) return 1; /* or the copying loop will go berserk */ } f= &(a->d[nw]); t=r->d; j=a->top-nw; r->top=j; if (rb == 0) { for (i=j+1; i > 0; i--) *(t++)= *(f++); } else { l= *(f++); for (i=1; i<j; i++) { tmp =(l>>rb)&BN_MASK2; l= *(f++); *(t++) =(tmp|(l<<lb))&BN_MASK2; } *(t++) =(l>>rb)&BN_MASK2; } *t=0; bn_fix_top(r); return(1); }
static int safenet_ecmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dp, const BIGNUM *dq, const BIGNUM *u, BN_CTX *ctx) { int to_return; expcrtmod_param_blk pb; to_return = 0; /* expect failure */ if(safenet_fd == -1) { SAFENETerr(SAFENET_F_SAFENET_MOD_EXP,SAFENET_R_NOT_LOADED); goto err; } /* Prepare the params */ bn_wexpand(r, p->top+q->top+2); r->top=p->top+q->top+2; pb.res = (unsigned int *)r->d; pb.ressize = p->top + q->top; pb.a = (unsigned int *)a->d; pb.asize = a->top; pb.p = (unsigned int *)p->d; pb.psize = p->top; pb.q = (unsigned int *)q->d; pb.qsize = q->top; pb.dp = (unsigned int *)dp->d; pb.dpsize = dp->top; pb.dq = (unsigned int *)dq->d; pb.dqsize = dq->top; pb.u = (unsigned int *)u->d; pb.usize = u->top; do { to_return = ioctl(safenet_fd, SAFENET_IOCEXPCRTMOD, &pb); } while(to_return<0 && errno==EINTR); if(to_return==FAIL_TO_SW) goto err; else if (to_return!=0) { to_return=0; goto err; } bn_fix_top(r); to_return = 1; err: return to_return; }
static int safenet_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { int to_return, rc; expmod_param_blk pb; to_return = 0; /* expect failure */ if(safenet_fd == -1) { SAFENETerr(SAFENET_F_SAFENET_MOD_EXP,SAFENET_R_NOT_LOADED); goto err; } /* Prepare the params */ bn_wexpand(r, m->top+2); r->top=m->top+2; /* Perform the operation */ pb.res = (unsigned int *)r->d; pb.ressize = m->top; pb.a = (unsigned int *)a->d; pb.asize = a->top; pb.p = (unsigned int *)p->d; pb.psize = p->top; pb.m = (unsigned int *)m->d; pb.msize = m->top; do { rc = ioctl( safenet_fd, SAFENET_IOCEXPMOD, &pb); } while(rc<0 && errno == EINTR); if(rc == FAIL_TO_SW ) { /* fall back to software if out of range for hw*/ BN_mod_exp(r,a,p,m,ctx); rc=0; } if( rc!=0 ) { SAFENETerr(SAFENET_F_SAFENET_MOD_EXP,SAFENET_R_REQUEST_FAILED); goto err; } /* Convert the response */ bn_fix_top(r); to_return = 1; err: return to_return; }
static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype) { EVP_PKEY *res = NULL; #ifndef OPENSSL_NO_RSA RSA *rsatmp = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsatmp=NULL; #endif char msg[64]="sureware_load_public"; int ret=0; if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey) { SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_NOT_INITIALISED); goto err; } switch (keytype) { #ifndef OPENSSL_NO_RSA case 1: /*RSA*/ /* set private external reference */ rsatmp = RSA_new_method(e); RSA_set_ex_data(rsatmp,rsaHndidx,hptr); rsatmp->flags |= RSA_FLAG_EXT_PKEY; /* set public big nums*/ rsatmp->e = BN_new(); rsatmp->n = BN_new(); bn_expand2(rsatmp->e, el/sizeof(BN_ULONG)); bn_expand2(rsatmp->n, el/sizeof(BN_ULONG)); if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))|| !rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG))) goto err; ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el, (unsigned long *)rsatmp->n->d, (unsigned long *)rsatmp->e->d); surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret); if (ret!=1) { SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); goto err; } /* normalise pub e and pub n */ rsatmp->e->top=el/sizeof(BN_ULONG); bn_fix_top(rsatmp->e); rsatmp->n->top=el/sizeof(BN_ULONG); bn_fix_top(rsatmp->n); /* create an EVP object: engine + rsa key */ res = EVP_PKEY_new(); EVP_PKEY_assign_RSA(res, rsatmp); break; #endif #ifndef OPENSSL_NO_DSA case 2:/*DSA*/ /* set private/public external reference */ dsatmp = DSA_new_method(e); DSA_set_ex_data(dsatmp,dsaHndidx,hptr); /*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/ /* set public key*/ dsatmp->pub_key = BN_new(); dsatmp->p = BN_new(); dsatmp->q = BN_new(); dsatmp->g = BN_new(); bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG)); bn_expand2(dsatmp->p, el/sizeof(BN_ULONG)); bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG)); bn_expand2(dsatmp->g, el/sizeof(BN_ULONG)); if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))|| !dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) || !dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) || !dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG))) goto err; ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el, (unsigned long *)dsatmp->pub_key->d, (unsigned long *)dsatmp->p->d, (unsigned long *)dsatmp->q->d, (unsigned long *)dsatmp->g->d); surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret); if (ret!=1) { SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY); goto err; } /* set parameters */ /* normalise pubkey and parameters in case of */ dsatmp->pub_key->top=el/sizeof(BN_ULONG); bn_fix_top(dsatmp->pub_key); dsatmp->p->top=el/sizeof(BN_ULONG); bn_fix_top(dsatmp->p); dsatmp->q->top=20/sizeof(BN_ULONG); bn_fix_top(dsatmp->q); dsatmp->g->top=el/sizeof(BN_ULONG); bn_fix_top(dsatmp->g); /* create an EVP object: engine + rsa key */ res = EVP_PKEY_new(); EVP_PKEY_assign_DSA(res, dsatmp); break; #endif default: SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PRIVATE_KEY); goto err; } return res; err: #ifndef OPENSSL_NO_RSA if (rsatmp) RSA_free(rsatmp); #endif #ifndef OPENSSL_NO_DSA if (dsatmp) DSA_free(dsatmp); #endif return NULL; }
int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { int top,al,bl; BIGNUM *rr; int ret = 0; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) int i; #endif #ifdef BN_COUNT printf("BN_mul %d * %d\n",a->top,b->top); #endif bn_check_top(a); bn_check_top(b); bn_check_top(r); al=a->top; bl=b->top; if ((al == 0) || (bl == 0)) { BN_zero(r); return(1); } top=al+bl; BN_CTX_start(ctx); if ((r == a) || (r == b)) { if ((rr = BN_CTX_get(ctx)) == NULL) goto err; } else rr = r; rr->neg=a->neg^b->neg; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) i = al-bl; #endif #ifdef BN_MUL_COMBA if (i == 0) { # if 0 if (al == 4) { if (bn_wexpand(rr,8) == NULL) goto err; rr->top=8; bn_mul_comba4(rr->d,a->d,b->d); goto end; } # endif if (al == 8) { if (bn_wexpand(rr,16) == NULL) goto err; rr->top=16; bn_mul_comba8(rr->d,a->d,b->d); goto end; } } #endif /* BN_MUL_COMBA */ if (bn_wexpand(rr,top) == NULL) goto err; rr->top=top; bn_mul_normal(rr->d,a->d,al,b->d,bl); #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif bn_fix_top(rr); if (r != rr) BN_copy(r,rr); ret=1; err: BN_CTX_end(ctx); return(ret); }
static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; HWCryptoHook_RSAKeyHandle *hptr; int to_return = 0, ret; rmsg.buf = tempbuf; rmsg.size = sizeof(tempbuf); if(!hwcrhk_context) { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,HWCRHK_R_NOT_INITIALISED); goto err; } /* This provides support for nForce keys. Since that's opaque data all we do is provide a handle to the proper key and let HWCryptoHook take care of the rest. */ if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) != NULL) { HWCryptoHook_MPI m_a, m_r; if(!rsa->n) { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_MISSING_KEY_COMPONENTS); goto err; } /* Prepare the params */ bn_expand2(r, rsa->n->top); /* Check for error !! */ BN2MPI(m_a, I); MPI2BN(r, m_r); /* Perform the operation */ ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); /* Convert the response */ r->top = m_r.size / sizeof(BN_ULONG); bn_fix_top(r); if (ret < 0) { /* FIXME: When this error is returned, HWCryptoHook is telling us that falling back to software computation might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK); } else { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; } } else { HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_MISSING_KEY_COMPONENTS); goto err; } /* Prepare the params */ bn_expand2(r, rsa->n->top); /* Check for error !! */ BN2MPI(m_a, I); BN2MPI(m_p, rsa->p); BN2MPI(m_q, rsa->q); BN2MPI(m_dmp1, rsa->dmp1); BN2MPI(m_dmq1, rsa->dmq1); BN2MPI(m_iqmp, rsa->iqmp); MPI2BN(r, m_r); /* Perform the operation */ ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg); /* Convert the response */ r->top = m_r.size / sizeof(BN_ULONG); bn_fix_top(r); if (ret < 0) { /* FIXME: When this error is returned, HWCryptoHook is telling us that falling back to software computation might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK); } else { HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; } } /* If we're here, we must be here with some semblance of success :-) */ to_return = 1; err: return to_return; }
/* unsigned subtraction of b from a, a must be larger than b. */ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { int max,min; register BN_ULONG t1,t2,*ap,*bp,*rp; int i,carry; #if defined(IRIX_CC_BUG) && !defined(LINT) int dummy; #endif bn_check_top(a); bn_check_top(b); if (a->top < b->top) /* hmm... should not be happening */ { return(0); } max=a->top; min=b->top; if (bn_wexpand(r,max) == NULL) return(0); ap=a->d; bp=b->d; rp=r->d; #if 1 carry=0; for (i=0; i<min; i++) { t1= *(ap++); t2= *(bp++); if (carry) { carry=(t1 <= t2); t1=(t1-t2-1)&BN_MASK2; } else { carry=(t1 < t2); t1=(t1-t2)&BN_MASK2; } #if defined(IRIX_CC_BUG) && !defined(LINT) dummy=t1; #endif *(rp++)=t1&BN_MASK2; } #else carry=bn_sub_words(rp,ap,bp,min); ap+=min; bp+=min; rp+=min; i=min; #endif if (carry) /* subtracted */ { while (i < max) { i++; t1= *(ap++); t2=(t1-1)&BN_MASK2; *(rp++)=t2; if (t1 > t2) break; } } #if 0 memcpy(rp,ap,sizeof(*rp)*(max-i)); #else if (rp != ap) { for (;;) { if (i++ >= max) break; rp[0]=ap[0]; if (i++ >= max) break; rp[1]=ap[1]; if (i++ >= max) break; rp[2]=ap[2]; if (i++ >= max) break; rp[3]=ap[3]; rp+=4; ap+=4; } } #endif r->top=max; bn_fix_top(r); return(1); }
int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { int top,al,bl; BIGNUM *rr; int ret = 0; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) int i; #endif #ifdef BN_RECURSION BIGNUM *t; int j,k; #endif #ifdef BN_COUNT printf("BN_mul %d * %d\n",a->top,b->top); #endif bn_check_top(a); bn_check_top(b); bn_check_top(r); al=a->top; bl=b->top; if ((al == 0) || (bl == 0)) { BN_zero(r); return(1); } top=al+bl; BN_CTX_start(ctx); if ((r == a) || (r == b)) { if ((rr = BN_CTX_get(ctx)) == NULL) goto err; } else rr = r; rr->neg=a->neg^b->neg; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) i = al-bl; #endif #ifdef BN_MUL_COMBA if (i == 0) { # if 0 if (al == 4) { if (bn_wexpand(rr,8) == NULL) goto err; rr->top=8; bn_mul_comba4(rr->d,a->d,b->d); goto end; } # endif if (al == 8) { if (bn_wexpand(rr,16) == NULL) goto err; rr->top=16; bn_mul_comba8(rr->d,a->d,b->d); goto end; } } #endif /* BN_MUL_COMBA */ #ifdef BN_RECURSION if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA)) { if (bn_wexpand(b,al) == NULL) goto err; b->d[bl]=0; bl++; i--; } else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA)) { if (bn_wexpand(a,bl) == NULL) goto err; a->d[al]=0; al++; i++; } if (i == 0) { /* symmetric and > 4 */ /* 16 or larger */ j=BN_num_bits_word((BN_ULONG)al); j=1<<(j-1); k=j+j; t = BN_CTX_get(ctx); if (al == j) /* exact multiple */ { if (bn_wexpand(t,k*2) == NULL) goto err; if (bn_wexpand(rr,k*2) == NULL) goto err; bn_mul_recursive(rr->d,a->d,b->d,al,t->d); } else { if (bn_wexpand(a,k) == NULL) goto err; if (bn_wexpand(b,k) == NULL) goto err; if (bn_wexpand(t,k*4) == NULL) goto err; if (bn_wexpand(rr,k*4) == NULL) goto err; for (i=a->top; i<k; i++) a->d[i]=0; for (i=b->top; i<k; i++) b->d[i]=0; bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); } rr->top=top; goto end; } } #endif /* BN_RECURSION */ if (bn_wexpand(rr,top) == NULL) goto err; rr->top=top; bn_mul_normal(rr->d,a->d,al,b->d,bl); #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif bn_fix_top(rr); if (r != rr) BN_copy(r,rr); ret=1; err: BN_CTX_end(ctx); return(ret); }
static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) { #ifndef OPENSSL_NO_RSA RSA *rtmp = NULL; #endif EVP_PKEY *res = NULL; #ifndef OPENSSL_NO_RSA HWCryptoHook_MPI e, n; HWCryptoHook_RSAKeyHandle *hptr; #endif #if !defined(OPENSSL_NO_RSA) char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; HWCryptoHook_PassphraseContext ppctx; #endif #if !defined(OPENSSL_NO_RSA) rmsg.buf = tempbuf; rmsg.size = sizeof(tempbuf); #endif if(!hwcrhk_context) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED); goto err; } #ifndef OPENSSL_NO_RSA hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); if (!hptr) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); goto err; } ppctx.ui_method = ui_method; ppctx.callback_data = callback_data; if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } if (!*hptr) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY); goto err; } #endif #ifndef OPENSSL_NO_RSA rtmp = RSA_new_method(eng); RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); rtmp->e = BN_new(); rtmp->n = BN_new(); rtmp->flags |= RSA_FLAG_EXT_PKEY; MPI2BN(rtmp->e, e); MPI2BN(rtmp->n, n); if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) != HWCRYPTOHOOK_ERROR_MPISIZE) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG)); bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG)); MPI2BN(rtmp->e, e); MPI2BN(rtmp->n, n); if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } rtmp->e->top = e.size / sizeof(BN_ULONG); bn_fix_top(rtmp->e); rtmp->n->top = n.size / sizeof(BN_ULONG); bn_fix_top(rtmp->n); res = EVP_PKEY_new(); EVP_PKEY_assign_RSA(res, rtmp); #endif if (!res) HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); return res; err: #ifndef OPENSSL_NO_RSA if (rtmp) RSA_free(rtmp); #endif return NULL; }
int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) { int retn=0; #ifdef MONT_WORD BIGNUM *n,*r; BN_ULONG *ap,*np,*rp,n0,v,*nrp; int al,nl,max,i,x,ri; BN_CTX_start(ctx); if ((r = BN_CTX_get(ctx)) == NULL) goto err; if (!BN_copy(r,a)) goto err; n= &(mont->N); ap=a->d; /* mont->ri is the size of mont->N in bits (rounded up to the word size) */ al=ri=mont->ri/BN_BITS2; nl=n->top; if ((al == 0) || (nl == 0)) { r->top=0; return(1); } max=(nl+al+1); /* allow for overflow (no?) XXX */ if (bn_wexpand(r,max) == NULL) goto err; if (bn_wexpand(ret,max) == NULL) goto err; r->neg=a->neg^n->neg; np=n->d; rp=r->d; nrp= &(r->d[nl]); /* clear the top words of T */ #if 1 for (i=r->top; i<max; i++) /* memset? XXX */ r->d[i]=0; #else memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); #endif r->top=max; n0=mont->n0; #ifdef BN_COUNT fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl); #endif for (i=0; i<nl; i++) { #ifdef __TANDEM { long long t1; long long t2; long long t3; t1 = rp[0] * (n0 & 0177777); t2 = 037777600000l; t2 = n0 & t2; t3 = rp[0] & 0177777; t2 = (t3 * t2) & BN_MASK2; t1 = t1 + t2; v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1); } #else v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); #endif nrp++; rp++; if (((nrp[-1]+=v)&BN_MASK2) >= v) continue; else { if (((++nrp[0])&BN_MASK2) != 0) continue; if (((++nrp[1])&BN_MASK2) != 0) continue; for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; } } bn_fix_top(r); /* mont->ri will be a multiple of the word size */ #if 0 BN_rshift(ret,r,mont->ri); #else ret->neg = r->neg; x=ri; rp=ret->d; ap= &(r->d[x]); if (r->top < x) al=0; else al=r->top-x; ret->top=al; al-=4; for (i=0; i<al; i+=4) { BN_ULONG t1,t2,t3,t4; t1=ap[i+0]; t2=ap[i+1]; t3=ap[i+2]; t4=ap[i+3]; rp[i+0]=t1; rp[i+1]=t2; rp[i+2]=t3; rp[i+3]=t4; } al+=4; for (; i<al; i++) rp[i]=ap[i]; #endif #else /* !MONT_WORD */ BIGNUM *t1,*t2; BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t1 == NULL || t2 == NULL) goto err; if (!BN_copy(t1,a)) goto err; BN_mask_bits(t1,mont->ri); if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err; BN_mask_bits(t2,mont->ri); if (!BN_mul(t1,t2,&mont->N,ctx)) goto err; if (!BN_add(t2,a,t1)) goto err; if (!BN_rshift(ret,t2,mont->ri)) goto err; #endif /* MONT_WORD */ if (BN_ucmp(ret, &(mont->N)) >= 0) { if (!BN_usub(ret,ret,&(mont->N))) goto err; } retn=1; err: BN_CTX_end(ctx); return(retn); }
int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) { int retn=0; BIGNUM *n,*r; BN_ULONG *ap,*np,*rp,n0,v,*nrp; int al,nl,max,i,x,ri; BN_CTX_start(ctx); if ((r = BN_CTX_get(ctx)) == NULL) goto err; if (!BN_copy(r,a)) goto err; n= &(mont->N); ap=a->d; /* mont->ri is the size of mont->N in bits (rounded up to the word size) */ al=ri=mont->ri/BN_BITS2; nl=n->top; if ((al == 0) || (nl == 0)) { r->top=0; return(1); } max=(nl+al+1); /* allow for overflow (no?) XXX */ if (bn_wexpand(r,max) == NULL) goto err; if (bn_wexpand(ret,max) == NULL) goto err; r->neg=a->neg^n->neg; np=n->d; rp=r->d; nrp= &(r->d[nl]); /* clear the top words of T */ for (i=r->top; i<max; i++) /* memset? XXX */ r->d[i]=0; r->top=max; n0=mont->n0; for (i=0; i<nl; i++) { v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); nrp++; rp++; if (((nrp[-1]+=v)&BN_MASK2) >= v) continue; else { if (((++nrp[0])&BN_MASK2) != 0) continue; if (((++nrp[1])&BN_MASK2) != 0) continue; for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; } } bn_fix_top(r); /* mont->ri will be a multiple of the word size */ ret->neg = r->neg; x=ri; rp=ret->d; ap= &(r->d[x]); if (r->top < x) al=0; else al=r->top-x; ret->top=al; al-=4; for (i=0; i<al; i+=4) { BN_ULONG t1,t2,t3,t4; t1=ap[i+0]; t2=ap[i+1]; t3=ap[i+2]; t4=ap[i+3]; rp[i+0]=t1; rp[i+1]=t2; rp[i+2]=t3; rp[i+3]=t4; } al+=4; for (; i<al; i++) rp[i]=ap[i]; if (BN_ucmp(ret, &(mont->N)) >= 0) { BN_usub(ret,ret,&(mont->N)); } retn=1; err: BN_CTX_end(ctx); return(retn); }
/* unsigned subtraction of b from a, a must be larger than b. */ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { int max,min; register BN_ULONG t1,t2,*ap,*bp,*rp; int i,carry; bn_check_top(a); bn_check_top(b); if (a->top < b->top) /* hmm... should not be happening */ return(0); max=a->top; min=b->top; if (bn_wexpand(r,max) == NULL) return(0); ap=a->d; bp=b->d; rp=r->d; carry=0; for (i=0; i<min; i++) { t1= *(ap++); t2= *(bp++); if (carry) { carry=(t1 <= t2); t1=(t1-t2-1)&BN_MASK2; } else { carry=(t1 < t2); t1=(t1-t2)&BN_MASK2; } *(rp++)=t1&BN_MASK2; } if (carry) /* subtracted */ { while (i < max) { i++; t1= *(ap++); t2=(t1-1)&BN_MASK2; *(rp++)=t2; if (t1 > t2) break; } } if (rp != ap) { for (;;) { if (i++ >= max) break; rp[0]=ap[0]; if (i++ >= max) break; rp[1]=ap[1]; if (i++ >= max) break; rp[2]=ap[2]; if (i++ >= max) break; rp[3]=ap[3]; rp+=4; ap+=4; } } r->top=max; bn_fix_top(r); return(1); }