Hi, Attached is a patch that causes the nCipher hardware support in OpenSSL 0.9.7b to fall back to software computation if a hardware problem is reported, naturally only for software keys. Other hardware implementations do similar things, and there are FIXME comments in 0.9.7b's hw_ncipher.c noting that this should be done.
Please let me know if I should produce this patch against a 0.9.8 snapshot as well or instead. [Resending because I wasn't subscribed to openssl-dev first time round; apologies if this arrives twice.] Cheers, -- Colin Watson [EMAIL PROTECTED] Software Engineer nCipher Corporation Limited
--- openssl-0.9.7b.orig/crypto/engine/hw_ncipher.c Thu Dec 12 17:41:34 2002 +++ openssl-0.9.7b/crypto/engine/hw_ncipher.c Wed Jul 23 18:10:21 2003 @@ -285,7 +285,9 @@ /* Stuff to pass to the HWCryptoHook library */ static HWCryptoHook_InitInfo hwcrhk_globals = { - HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */ + HWCryptoHook_InitFlags_SimpleForkCheck | + HWCryptoHook_InitFlags_FallbackModExp | + HWCryptoHook_InitFlags_FallbackRSAImmed, /* Flags */ &logstream, /* logstream */ sizeof(BN_ULONG), /* limbsize */ 0, /* mslimb first: false for BNs */ @@ -938,19 +940,12 @@ r->top = m_r.size / sizeof(BN_ULONG); bn_fix_top(r); + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) + return ret; + 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); - } + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED); ERR_add_error_data(1,rmsg.buf); goto err; } @@ -1006,13 +1001,11 @@ 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); + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + to_return = (*meth->rsa_mod_exp)(r, I, rsa); + goto err; } else { @@ -1054,13 +1047,11 @@ 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); + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + to_return = (*meth->rsa_mod_exp)(r, I, rsa); + goto err; } else { @@ -1082,7 +1073,13 @@ static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { - return hwcrhk_mod_exp(r, a, p, m, ctx); + int ret = hwcrhk_mod_exp(r, a, p, m, ctx); + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx); + } + return ret; } #ifndef OPENSSL_NO_DH @@ -1091,7 +1088,13 @@ const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { - return hwcrhk_mod_exp(r, a, p, m, ctx); + int ret = hwcrhk_mod_exp(r, a, p, m, ctx); + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + const DH_METHOD *meth = DH_OpenSSL(); + ret = (*meth->bn_mod_exp)(dh, r, a, p, m, ctx, m_ctx); + } + return ret; } #endif @@ -1113,21 +1116,18 @@ } ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); + + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + const RAND_METHOD *meth = RAND_SSLeay(); + meth->seed(buf, num); + return meth->bytes(buf, num); + } + 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_RAND_BYTES, - HWCRHK_R_REQUEST_FALLBACK); - } - else - { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, - HWCRHK_R_REQUEST_FAILED); - } + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, + HWCRHK_R_REQUEST_FAILED); ERR_add_error_data(1,rmsg.buf); goto err; }