/* 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; }
static int gmp2bn(mpz_t g, BIGNUM *bn) { if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && (BN_BITS2 == GMP_NUMB_BITS)) { /* The common case */ int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size; BN_zero(bn); if(bn_expand2 (bn, s) == NULL) return 0; bn->top = s; TINYCLR_SSL_MEMCPY(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0])); bn_correct_top(bn); bn->neg = g->_mp_size >= 0 ? 0 : 1; return 1; } else { int toret; char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10); if(!tmpchar) return 0; mpz_get_str(tmpchar, 16, g); toret = BN_hex2bn(&bn, tmpchar); OPENSSL_free(tmpchar); return toret; } }
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; }
/* 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; }
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; }
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; }
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; }