提交 f11fd3f4 编写于 作者: R Richard Levitte

Implement failover for ubsec. Submitted by Subramanian Ramamoorthy

<sram@broadcom.com> with the following comment:

[...] We have implemented failover (ie, if for some reason that the
hardware fails, the implementation detects this failure and performs
this operation as if no hardware is present, ie, in software) for
sometime now and have tested it here with our hardware. [...]

This change was cc:ed to exports@crypto.com
上级 29b108f9
......@@ -73,6 +73,8 @@
#include "vendor_defns/hw_ubsec.h"
#endif
#define FAIL_TO_SOFTWARE -15
static int ubsec_destroy(ENGINE *e);
static int ubsec_init(ENGINE *e);
static int ubsec_finish(ENGINE *e);
......@@ -184,6 +186,7 @@ static DH_METHOD ubsec_dh =
#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 105
#define UBSEC_F_UBSEC_DSA_SIGN 106
#define UBSEC_F_UBSEC_DSA_VERIFY 107
#define UBSEC_F_UBSEC_DH_COMPUTE_KEY 117
/* Error reason codes */
#define UBSEC_R_ALREADY_LOADED 108
#define UBSEC_R_DSO_FAILURE 109
......@@ -194,6 +197,7 @@ static DH_METHOD ubsec_dh =
#define UBSEC_R_BN_EXPAND_FAIL 114
#define UBSEC_R_REQUEST_FAILED 115
#define UBSEC_R_MISSING_KEY_COMPONENTS 116
static ERR_STRING_DATA ubsec_str_functs[] =
{
/* This first element is changed to match the dynamic 'lib' number */
......@@ -361,6 +365,9 @@ static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
#endif
static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
static int max_key_len = 1024; /* ??? */
/*
* These are the static string constants for the DSO file name and the function
......@@ -386,6 +393,7 @@ static const char *UBSEC_F10 = "dsa_verify_ioctl";
#endif
static const char *UBSEC_F11 = "math_accelerate_ioctl";
static const char *UBSEC_F12 = "rng_ioctl";
static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
/* Destructor (complements the "ENGINE_ubsec()" constructor) */
static int ubsec_destroy(ENGINE *e)
......@@ -415,6 +423,7 @@ static int ubsec_init(ENGINE *e)
#endif
t_UBSEC_math_accelerate_ioctl *p11;
t_UBSEC_rng_ioctl *p12;
t_UBSEC_max_key_len_ioctl *p13;
int fd = 0;
if(ubsec_dso != NULL)
......@@ -453,7 +462,8 @@ static int ubsec_init(ENGINE *e)
#endif
!(p11 = (t_UBSEC_math_accelerate_ioctl *)
DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
!(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)))
!(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
!(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
{
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
goto err;
......@@ -478,17 +488,18 @@ static int ubsec_init(ENGINE *e)
#endif
p_UBSEC_math_accelerate_ioctl = p11;
p_UBSEC_rng_ioctl = p12;
p_UBSEC_max_key_len_ioctl = p13;
/* Perform an open to see if there's actually any unit running. */
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0)
{
p_UBSEC_ubsec_close(fd);
return 1;
}
if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
{
p_UBSEC_ubsec_close(fd);
return 1;
}
else
{
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
}
{
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
}
err:
if(ubsec_dso)
......@@ -511,6 +522,7 @@ err:
#endif
p_UBSEC_math_accelerate_ioctl = NULL;
p_UBSEC_rng_ioctl = NULL;
p_UBSEC_max_key_len_ioctl = NULL;
return 0;
}
......@@ -546,6 +558,7 @@ static int ubsec_finish(ENGINE *e)
#endif
p_UBSEC_math_accelerate_ioctl = NULL;
p_UBSEC_rng_ioctl = NULL;
p_UBSEC_max_key_len_ioctl = NULL;
return 1;
}
......@@ -588,9 +601,9 @@ static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
/* Check if hardware can't handle this argument. */
y_len = BN_num_bits(m);
if (y_len > 1024) {
if (y_len > max_key_len) {
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
return 0;
return BN_mod_exp(r, a, p, m, ctx);
}
if(!bn_wexpand(r, m->top))
......@@ -603,7 +616,7 @@ static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
fd = 0;
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
return 0;
return BN_mod_exp(r, a, p, m, ctx);
}
if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
......@@ -611,7 +624,9 @@ static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
{
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
return 0;
p_UBSEC_ubsec_close(fd);
return BN_mod_exp(r, a, p, m, ctx);
}
p_UBSEC_ubsec_close(fd);
......@@ -635,15 +650,15 @@ static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
goto err;
}
/*
* Do in software if argument is too large for hardware.
*/
if ((BN_num_bits(rsa->p)+BN_num_bits(rsa->q)) > 1024) {
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
} else {
to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
rsa->dmq1, rsa->iqmp, ctx);
to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
rsa->dmq1, rsa->iqmp, ctx);
if (to_return == FAIL_TO_SOFTWARE)
{
/*
* Do in software as hardware failed.
*/
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
}
err:
if(ctx)
......@@ -664,9 +679,9 @@ static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
y_len = BN_num_bits(p) + BN_num_bits(q);
/* Check if hardware can't handle this argument. */
if (y_len > 1024) {
if (y_len > max_key_len) {
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
return 0;
return FAIL_TO_SOFTWARE;
}
if (!bn_wexpand(r, p->top + q->top + 1)) {
......@@ -677,7 +692,7 @@ static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
fd = 0;
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
return 0;
return FAIL_TO_SOFTWARE;
}
if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
......@@ -689,7 +704,8 @@ static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
(unsigned char *)q->d, BN_num_bits(q),
(unsigned char *)r->d, &y_len) != 0) {
UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
return 0;
p_UBSEC_ubsec_close(fd);
return FAIL_TO_SOFTWARE;
}
p_UBSEC_ubsec_close(fd);
......@@ -739,7 +755,7 @@ static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
#ifndef OPENSSL_NO_RSA
/* Do in software if the key is too large for the hardware. */
if (BN_num_bits(m) > 1024)
if (BN_num_bits(m) > max_key_len)
{
const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
......@@ -791,9 +807,12 @@ static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
}
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
const DSA_METHOD *meth;
fd = 0;
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
return 0;
meth = DSA_OpenSSL();
to_return = meth->dsa_do_sign(dgst, dlen, dsa);
goto err;
}
if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
......@@ -805,7 +824,13 @@ static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
(unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
(unsigned char *)r->d, &r_len,
(unsigned char *)s->d, &s_len ) != 0) {
const DSA_METHOD *meth;
UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_REQUEST_FAILED);
p_UBSEC_ubsec_close(fd);
meth = DSA_OpenSSL();
to_return = meth->dsa_do_sign(dgst, dlen, dsa);
goto err;
}
......@@ -852,9 +877,12 @@ static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
const DSA_METHOD *meth;
fd = 0;
UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
return 0;
meth = DSA_OpenSSL();
to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
goto err;
}
if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
......@@ -866,7 +894,13 @@ static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
(unsigned char *)sig->r->d, BN_num_bits(sig->r),
(unsigned char *)sig->s->d, BN_num_bits(sig->s),
(unsigned char *)v.d, &v_len) != 0) {
const DSA_METHOD *meth;
UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY , UBSEC_R_REQUEST_FAILED);
p_UBSEC_ubsec_close(fd);
meth = DSA_OpenSSL();
to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
goto err;
}
......@@ -881,21 +915,176 @@ err:
#ifndef OPENSSL_NO_DH
static int ubsec_dh_compute_key (unsigned char *key,const BIGNUM *pub_key,DH *dh)
{
return 0;
}
{
int ret = -1,
k_len,
fd;
k_len = BN_num_bits(dh->p);
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
{
const DH_METHOD *meth;
ENGINEerr(UBSEC_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
meth = DH_OpenSSL();
ret = meth->compute_key(key, pub_key, dh);
goto err;
}
if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
(unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
(unsigned char *)pub_key->d, BN_num_bits(pub_key),
(unsigned char *)dh->p->d, BN_num_bits(dh->p),
key, &k_len) != 0)
{
/* Hardware's a no go, failover to software */
const DH_METHOD *meth;
ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, ENGINE_R_REQUEST_FAILED);
p_UBSEC_ubsec_close(fd);
meth = DH_OpenSSL();
ret = meth->compute_key(key, pub_key, dh);
goto err;
}
p_UBSEC_ubsec_close(fd);
ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
err:
return ret;
}
static int ubsec_dh_generate_key (DH *dh)
{
return 0;
}
{
int ret = 0,
random_bits = 0,
pub_key_len = 0,
priv_key_len = 0,
fd;
BIGNUM *pub_key = NULL;
BIGNUM *priv_key = NULL;
/*
* How many bits should Random x be? dh_key.c
* sets the range from 0 to num_bits(modulus) ???
*/
if (dh->priv_key == NULL)
{
priv_key = BN_new();
if (priv_key == NULL) goto err;
priv_key_len = BN_num_bits(dh->p);
bn_wexpand(priv_key, dh->p->top);
do
if (!BN_rand_range(priv_key, dh->p)) goto err;
while (BN_is_zero(priv_key));
random_bits = BN_num_bits(priv_key);
}
else
{
priv_key = dh->priv_key;
}
if (dh->pub_key == NULL)
{
pub_key = BN_new();
pub_key_len = BN_num_bits(dh->p);
bn_wexpand(pub_key, dh->p->top);
if(pub_key == NULL) goto err;
}
else
{
pub_key = dh->pub_key;
}
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
{
const DH_METHOD *meth;
ENGINEerr(UBSEC_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
meth = DH_OpenSSL();
ret = meth->generate_key(dh);
goto err;
}
if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
(unsigned char *)priv_key->d, &priv_key_len,
(unsigned char *)pub_key->d, &pub_key_len,
(unsigned char *)dh->g->d, BN_num_bits(dh->g),
(unsigned char *)dh->p->d, BN_num_bits(dh->p),
0, 0, random_bits) != 0)
{
/* Hardware's a no go, failover to software */
const DH_METHOD *meth;
ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, ENGINE_R_REQUEST_FAILED);
p_UBSEC_ubsec_close(fd);
meth = DH_OpenSSL();
ret = meth->generate_key(dh);
goto err;
}
p_UBSEC_ubsec_close(fd);
dh->pub_key = pub_key;
dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
dh->priv_key = priv_key;
dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
ret = 1;
err:
return ret;
}
#endif
#ifdef NOT_USED
static int ubsec_rand_bytes(unsigned char *buf, int num)
{
return 0;
}
#if NOT_USED
static int ubsec_rand_bytes(unsigned char * buf,
int num)
{
int ret = 0,
fd;
if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
{
const RAND_METHOD *meth;
ENGINEerr(UBSEC_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE);
num = p_UBSEC_ubsec_bits_to_bytes(num);
meth = RAND_SSLeay();
meth->seed(buf, num);
ret = meth->bytes(buf, num);
goto err;
}
num *= 8; /* bytes to bits */
if (p_UBSEC_rng_ioctl(fd,
UBSEC_RNG_DIRECT,
buf,
&num) != 0)
{
/* Hardware's a no go, failover to software */
const RAND_METHOD *meth;
ENGINEerr(UBSEC_F_UBSEC_RNG_BYTES, ENGINE_R_REQUEST_FAILED);
p_UBSEC_ubsec_close(fd);
num = p_UBSEC_ubsec_bits_to_bytes(num);
meth = RAND_SSLeay();
meth->seed(buf, num);
ret = meth->bytes(buf, num);
goto err;
}
p_UBSEC_ubsec_close(fd);
ret = 1;
err:
return(ret);
}
static int ubsec_rand_status(void)
{
......
......@@ -97,3 +97,4 @@ typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command,
typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command,
unsigned char *Result, int *Result_len);
typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册