Hi, I'm signing and verifying documents using DSA and have run into a couple of problems.
I'm working with OpenSSL 0.9.7 on Linux with a Broadcom crypto card based on the 5821 (so OpenSSL engine type is "ubsec"). I have version 1.81 of the Broadcom driver. (1) While testing I found that verification of certain signed documents crashed OpenSSL. The problem appears to be that hw_ubsec.c:ubsec_dsa_verify() calls p_UBSEC_dsa_verify_ioctl() and if this call fails then the code tries using software crypto, indirectly calling dsa_ossl.c:dsa_do_verify(). However, dsa_do_verify() tries to do: if (!ENGINE_get_DSA(dsa->engine)->dsa_mod_exp(dsa, &t1,dsa->g,&u1, dsa->pub_key,&u2, dsa->p,ctx,mont)) goto err; and this dies because dsa_mod_exp is NULL. The current workaround is to set up pointers in ubsec_dsa for dsa_mod_exp and dsa_bn_mod_exp (just in case): #ifndef OPENSSL_NO_DSA static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) { return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont); } static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); } /* Our internal DSA_METHOD that we provide pointers to */ static DSA_METHOD ubsec_dsa = { "UBSEC DSA method", ubsec_dsa_do_sign, /* dsa_do_sign */ NULL, /* dsa_sign_setup */ ubsec_dsa_verify, /* dsa_do_verify */ dsa_mod_exp, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */ dsa_bn_mod_exp, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */ NULL, /* init */ NULL, /* finish */ 0, /* flags */ NULL /* app_data */ }; #endif Not sure if this is entirely kosher, but I don't know why they were NULL to begin with? (2) The next question is why did the original call to p_UBSEC_dsa_verify_ioctl() fail, since the Broadcom card is present and functioning? The answer is that one of the arguments passed in this ioctl call is the length in bits of the hash (which is what was signed and we're trying to verify). If the hash happens to start with > 7 zero bits then when the bit size is converted back to bytes the number of bytes will be < 20. And deep in the Broadcom driver this length will get rejected because the driver insists the hash is 20 bytes long due to alignment issues. (If you have access to the Broadcom driver see ubsec_key.c:dsa_verify_ioctl() where the length is converted from bits to bytes, and param.c:ubsec_keysetup_DSA() where the length is checked against 20). I think the solution here is to just always pass the hash length as 160 bits and pad it with zeroes to make it the full 20 bytes long. I haven't tested this though. Maybe there is an issue here in the way the API is defined? (3) Further testing showed that DSA signatures created using OpenSSL with the Broadcom card appear to be broken in general somehow. I've attached a tar file containing a DSA private/public key pair, a small test file to sign, and a script which does a bunch of DSA sign and verify tests. What these tests show is that a DSA signature generated using the Broadcom card will fail to verify if the Broadcom card is not used during the verification. The inverse, using a card to verify a signature created without the card, works fine. I don't know whether the issue lies in the card, the driver, OpenSSL, or some combination. (IBM's xss4j tool also cannot verify DSA signatures generated using OpenSSL with the Broadcom card, though it can verify signatures generated without using the Broadcom card.) (4) To further complicate the last problem, in the tar file there is a file "testfile-crash" which causes OpenSSL to segfault when used with the Broadcom card for signing. It looks like another case of a NULL pointer in the ubsec_dsa function table, in this case for dsa_sign_setup. I've tried making dsa_sign_setup global and sticking it in the table and this seems to prevent the crash, though I'm getting some error messages about memory leaks (it's a debug build). I don't understand the layers of function pointer tables being used with the engine stuff so I'm not sure what the real way is to fix this, or why it happens sometimes and not others. Does anyone have experience with the Broadcom card and DSA and maybe can confirm that I'm on the right track with my "fixes", and maybe shed some light on the invalid DSA signatures? I'm trying to get in touch with Broadcom as well to find out if they have a later driver. So far their response has been that they've tested with OpenSSL and DSA and they work fine for them. Thanks, -- Jonathan __________________________________________________ Do you Yahoo!? Yahoo! Shopping - Send Flowers for Valentine's Day http://shopping.yahoo.com
dsa-ubsec-test.tar.gz
Description: dsa-ubsec-test.tar.gz