From 71c8e9f1c347e2870400d6ccf43e9b625c4a4c01 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 25 May 2000 21:21:03 +0000 Subject: [PATCH] Added Geoff's latest changes, which seems to mostly be DH stuff and a README. Oh, and a test program. --- crypto/engine/README | 38 +++++++++++ crypto/engine/engine_lib.c | 25 ++++++++ crypto/engine/engine_openssl.c | 2 +- crypto/engine/enginetest.c | 6 +- crypto/engine/hw_cswift.c | 98 +++++++++++++++++++---------- crypto/engine/vendor_defns/cswift.h | 2 +- test/Makefile.ssl | 6 +- util/libeay.num | 44 +++++++++++++ util/mkdef.pl | 1 - 9 files changed, 183 insertions(+), 39 deletions(-) create mode 100644 crypto/engine/README diff --git a/crypto/engine/README b/crypto/engine/README new file mode 100644 index 0000000000..0d07ebf1be --- /dev/null +++ b/crypto/engine/README @@ -0,0 +1,38 @@ +NOTES, THOUGHTS, and EVERYTHING +------------------------------- + +(1) Maybe ENGINE_get_struct_size() isn't such a good idea. All ENGINEs + should be allocated from within OpenSSL (rather than, for example, + a loaded DSO). Two reasons, (i) DSOs authors are likely to stash + the return value as an assumed constant and so everything will + break down horribly when OpenSSL is changed/expanded, (ii) with + the structure allocated within OpenSSL, we could handle the case + where a DSO *really* wants to close down and lick its wounds even + if there are still references because we could simply NULL out the + pointers in the structure. If I change this, I should also + remember to get rid of the parameter in ENGINE_new() as it would + serve no purpose and is likely to confuse. + +(2) Concurrency and locking ... I made a change to the ENGINE_free code + because I spotted a potential hold-up in proceedings (doing too + much inside a lock including calling a callback), there may be + other bits like this. What do the speed/optimisation freaks think + of this aspect of the code and design? There's lots of locking for + manipulation functions and I need that to keep things nice and + solid, but this manipulation is mostly (de)initialisation, I would + think that most run-time locking is purely in the ENGINE_init and + ENGINE_finish calls that might be made when getting handles for + RSA (and friends') structures, and these would be mostly reference + count operations as the functional references should always be 1 + or greater at run-time to prevent init/deinit thrashing. + +(3) Atalla isn't finished quite yet. + +(4) The DH stuff was added to the CryptoSwift code without testing + because it should work trivially and didn't involve adding more of + the cropped bits from Rainbow's headers back into the vendor_defns + stuff. (Also, randomness should be easy to add soon when I sort + the headers out a bit more which would give hw_cswift a full + suite). + +(5) Another make update is probably due ... diff --git a/crypto/engine/engine_lib.c b/crypto/engine/engine_lib.c index 787ebe9547..2ef27db813 100644 --- a/crypto/engine/engine_lib.c +++ b/crypto/engine/engine_lib.c @@ -177,6 +177,7 @@ int ENGINE_finish(ENGINE *e) } CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if((e->funct_ref == 1) && e->finish) +#if 0 /* This is the last functional reference and the engine * requires cleanup so we do it now. */ to_return = e->finish(); @@ -188,6 +189,30 @@ int ENGINE_finish(ENGINE *e) e->funct_ref--; } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +#else + /* I'm going to deliberately do a convoluted version of this + * piece of code because we don't want "finish" functions + * being called inside a locked block of code, if at all + * possible. I'd rather have this call take an extra couple + * of ticks than have throughput serialised on a externally- + * provided callback function that may conceivably never come + * back. :-( */ + { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* CODE ALERT: This *IS* supposed to be "=" and NOT "==" :-) */ + if((to_return = e->finish())) + { + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* Cleanup the functional reference which is also a + * structural reference. */ + e->struct_ref--; + e->funct_ref--; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + } + } + else + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +#endif return to_return; } diff --git a/crypto/engine/engine_openssl.c b/crypto/engine/engine_openssl.c index 4c760bde2d..8ecd91a6ac 100644 --- a/crypto/engine/engine_openssl.c +++ b/crypto/engine/engine_openssl.c @@ -80,7 +80,7 @@ static int openssl_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, static ENGINE engine_openssl = { "openssl", - "Software default 'hardware' support", + "Software default engine support", NULL, NULL, NULL, /* these methods are "stolen" in ENGINE_openssl() */ diff --git a/crypto/engine/enginetest.c b/crypto/engine/enginetest.c index 7fdd395b42..2772bde7ca 100644 --- a/crypto/engine/enginetest.c +++ b/crypto/engine/enginetest.c @@ -191,7 +191,7 @@ int main(int argc, char *argv[]) } else printf("Successfully added and removed to an empty list!\n"); - printf("About to fill up the engine type array\n"); + printf("About to beef up the engine-type list\n"); for(loop = 0; loop < 512; loop++) { sprintf(buf, "id%i", loop); @@ -220,7 +220,7 @@ int main(int argc, char *argv[]) printf("."); fflush(stdout); } cleanup_loop: - printf("\nAbout to empty the engine type array\n"); + printf("\nAbout to empty the engine-type list\n"); while((ptr = ENGINE_get_first()) != NULL) { if(!ENGINE_remove(ptr)) @@ -235,7 +235,7 @@ cleanup_loop: free((char *)(ENGINE_get_id(block[loop]))); free((char *)(ENGINE_get_name(block[loop]))); } - printf("\nTests complete\n"); + printf("\nTests completed happily\n"); to_return = 0; end: if(to_return) diff --git a/crypto/engine/hw_cswift.c b/crypto/engine/hw_cswift.c index ca73599e73..dc160ff537 100644 --- a/crypto/engine/hw_cswift.c +++ b/crypto/engine/hw_cswift.c @@ -67,7 +67,7 @@ /* Attribution notice: Rainbow have generously allowed me to reproduce * the necessary definitions here from their API. This means the support - * can build independantly of whether application builders have the + * can build independently of whether application builders have the * API or hardware. This will allow developers to easily produce software * that has latent hardware support for any users that have accelerators * installed, without the developers themselves needing anything extra. @@ -92,8 +92,11 @@ static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); /* This function is aliased to mod_exp (with the mont stuff dropped). */ static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -/* Our internal RSA_METHOD that we provide const pointers to */ +/* Our internal RSA_METHOD that we provide pointers to */ static RSA_METHOD cswift_rsa = { "CryptoSwift RSA method", @@ -111,14 +114,27 @@ static RSA_METHOD cswift_rsa = NULL }; +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD cswift_dh = + { + "CryptoSwift DH method", + NULL, + NULL, + cswift_mod_exp_dh, + NULL, + NULL, + 0, + NULL + }; + /* Our ENGINE structure. */ static ENGINE engine_cswift = { "cswift", - "CryptoSwift hardware support", + "CryptoSwift hardware engine support", &cswift_rsa, NULL, - NULL, + &cswift_dh, NULL, cswift_mod_exp, cswift_mod_exp_crt, @@ -133,7 +149,8 @@ static ENGINE engine_cswift = * (indeed - the lock will already be held by our caller!!!) */ ENGINE *ENGINE_cswift() { - RSA_METHOD *meth; + RSA_METHOD *meth1; + DH_METHOD *meth2; /* We know that the "PKCS1_SSLeay()" functions hook properly * to the cswift-specific mod_exp and mod_exp_crt so we use @@ -142,11 +159,16 @@ ENGINE *ENGINE_cswift() * code may not hook properly, and if you own one of these * cards then you have the right to do RSA operations on it * anyway! */ - meth = RSA_PKCS1_SSLeay(); - cswift_rsa.rsa_pub_enc = meth->rsa_pub_enc; - cswift_rsa.rsa_pub_dec = meth->rsa_pub_dec; - cswift_rsa.rsa_priv_enc = meth->rsa_priv_enc; - cswift_rsa.rsa_priv_dec = meth->rsa_priv_dec; + meth1 = RSA_PKCS1_SSLeay(); + cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + + /* Much the same for Diffie-Hellman */ + meth2 = DH_OpenSSL(); + cswift_dh.generate_key = meth2->generate_key; + cswift_dh.compute_key = meth2->compute_key; return &engine_cswift; } @@ -310,10 +332,12 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, goto err; } sw_param.type = SW_ALG_EXP; - sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, (char *)modulus->d); - sw_param.up.exp.modulus.value = (char *)modulus->d; - sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, (char *)exponent->d); - sw_param.up.exp.exponent.value = (char *)exponent->d; + sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, + (unsigned char *)modulus->d); + sw_param.up.exp.modulus.value = (unsigned char *)modulus->d; + sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, + (unsigned char *)exponent->d); + sw_param.up.exp.exponent.value = (unsigned char *)exponent->d; /* Attach the key params */ if(p_CSwift_AttachKeyParam(hac, &sw_param) != SW_OK) { @@ -321,11 +345,11 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, goto err; } /* Prepare the argument and response */ - arg.nbytes = BN_bn2bin(a, (char *)argument->d); - arg.value = (char *)argument->d; + arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); + arg.value = (unsigned char *)argument->d; res.nbytes = BN_num_bytes(m); memset(result->d, 0, res.nbytes); - res.value = (char *)result->d; + res.value = (unsigned char *)result->d; /* Perform the operation */ if(p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, &res, 1) != SW_OK) { @@ -333,7 +357,7 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, goto err; } /* Convert the response */ - BN_bin2bn((char *)result->d, res.nbytes, r); + BN_bin2bn((unsigned char *)result->d, res.nbytes, r); to_return = 1; err: if(acquired) @@ -398,16 +422,19 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, goto err; } sw_param.type = SW_ALG_CRT; - sw_param.up.crt.p.nbytes = BN_bn2bin(p, (char *)rsa_p->d); - sw_param.up.crt.p.value = (char *)rsa_p->d; - sw_param.up.crt.q.nbytes = BN_bn2bin(q, (char *)rsa_q->d); - sw_param.up.crt.q.value = (char *)rsa_q->d; - sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1, (char *)rsa_dmp1->d); - sw_param.up.crt.dmp1.value = (char *)rsa_dmp1->d; - sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1, (char *)rsa_dmq1->d); - sw_param.up.crt.dmq1.value = (char *)rsa_dmq1->d; - sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp, (char *)rsa_iqmp->d); - sw_param.up.crt.iqmp.value = (char *)rsa_iqmp->d; + sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d); + sw_param.up.crt.p.value = (unsigned char *)rsa_p->d; + sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d); + sw_param.up.crt.q.value = (unsigned char *)rsa_q->d; + sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1, + (unsigned char *)rsa_dmp1->d); + sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d; + sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1, + (unsigned char *)rsa_dmq1->d); + sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d; + sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp, + (unsigned char *)rsa_iqmp->d); + sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d; /* Attach the key params */ if(p_CSwift_AttachKeyParam(hac, &sw_param) != SW_OK) { @@ -415,11 +442,11 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, goto err; } /* Prepare the argument and response */ - arg.nbytes = BN_bn2bin(a, (char *)argument->d); - arg.value = (char *)argument->d; + arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); + arg.value = (unsigned char *)argument->d; res.nbytes = 2 * BN_num_bytes(p); memset(result->d, 0, res.nbytes); - res.value = (char *)result->d; + res.value = (unsigned char *)result->d; /* Perform the operation */ if(p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1, &res, 1) != SW_OK) @@ -428,7 +455,7 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, goto err; } /* Convert the response */ - BN_bin2bn((char *)result->d, res.nbytes, r); + BN_bin2bn((unsigned char *)result->d, res.nbytes, r); to_return = 1; err: if(acquired) @@ -470,5 +497,12 @@ static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, return cswift_mod_exp(r, a, p, m, ctx); } +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return cswift_mod_exp(r, a, p, m, ctx); + } + #endif /* HW_CSWIFT */ diff --git a/crypto/engine/vendor_defns/cswift.h b/crypto/engine/vendor_defns/cswift.h index 6048048c36..cbf6836359 100644 --- a/crypto/engine/vendor_defns/cswift.h +++ b/crypto/engine/vendor_defns/cswift.h @@ -1,6 +1,6 @@ /* Attribution notice: Rainbow have generously allowed me to reproduce * the necessary definitions here from their API. This means the support - * can build independantly of whether application builders have the + * can build independently of whether application builders have the * API or hardware. This will allow developers to easily produce software * that has latent hardware support for any users that have accelertors * installed, without the developers themselves needing anything extra. diff --git a/test/Makefile.ssl b/test/Makefile.ssl index 480c697a88..76bd1d0832 100644 --- a/test/Makefile.ssl +++ b/test/Makefile.ssl @@ -103,7 +103,7 @@ tests: exe apps \ test_rmd test_rc2 test_rc4 test_rc5 test_bf test_cast \ test_rand test_bn test_enc test_x509 test_rsa test_crl test_sid \ test_gen test_req test_pkcs7 test_verify test_dh test_dsa \ - test_ss test_ca test_ssl + test_ss test_ca test_engine test_ssl apps: @(cd ../apps; $(MAKE) CC='${CC}' CFLAG='${CFLAG}' INSTALLTOP='${INSTALLTOP}' PEX_LIBS='${PEX_LIBS}' EX_LIBS='${EX_LIBS}' all) @@ -211,6 +211,10 @@ test_ss keyU.ss certU.ss certCA.ss: testss @echo "Generate and certify a test certificate" @sh ./testss +test_engine: + @echo "Manipulate the ENGINE structures" + ./$(ENGINETEST) + test_ssl: keyU.ss certU.ss certCA.ss @echo "test SSL protocol" @sh ./testssl keyU.ss certU.ss certCA.ss diff --git a/util/libeay.num b/util/libeay.num index 03c8ee21e1..02459aaf3b 100755 --- a/util/libeay.num +++ b/util/libeay.num @@ -2370,3 +2370,47 @@ sk_BIO_pop 2395 sk_BIO_pop_free 2396 d2i_ASN1_SET_OF_PKCS7 2397 sk_ASN1_INTEGER_insert 2398 +ERR_load_ENGINE_strings 2399 +ENGINE_set_DSA 2400 +ENGINE_get_default_RSA 2401 +ENGINE_init 2402 +RSA_set_default_openssl_method 2403 +ENGINE_finish 2404 +ENGINE_get_DH 2405 +ENGINE_get_last 2406 +ENGINE_get_RSA 2407 +ENGINE_get_RAND 2408 +ENGINE_get_default_BN_mod_exp_crt 2409 +ENGINE_remove 2410 +ENGINE_get_BN_mod_exp_crt 2411 +ENGINE_set_name 2412 +ENGINE_get_default_DSA 2413 +ENGINE_set_default_BN_mod_exp 2414 +ENGINE_set_default_RSA 2415 +ENGINE_get_default_RAND 2416 +ENGINE_get_default_BN_mod_exp 2417 +ENGINE_get_id 2418 +ENGINE_add 2419 +ENGINE_get_DSA 2420 +ENGINE_get_BN_mod_exp 2421 +ENGINE_set_DH 2422 +ENGINE_set_default_BN_mod_exp_crt 2423 +ENGINE_get_struct_size 2424 +ENGINE_set_default_DSA 2425 +ENGINE_get_name 2426 +ENGINE_get_prev 2427 +ENGINE_get_default_DH 2428 +ENGINE_set_default 2429 +ENGINE_by_id 2430 +ENGINE_get_first 2431 +RSA_get_default_openssl_method 2432 +ENGINE_set_RSA 2433 +ENGINE_set_default_RAND 2434 +ENGINE_set_BN_mod_exp 2435 +ENGINE_free 2436 +ENGINE_get_next 2437 +ENGINE_set_RAND 2438 +ENGINE_set_id 2439 +ENGINE_set_BN_mod_exp_crt 2440 +ENGINE_set_default_DH 2441 +ENGINE_new 2442 diff --git a/util/mkdef.pl b/util/mkdef.pl index 91c194820a..3e2fffe11b 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -102,7 +102,6 @@ $crypto.=" crypto/dsa/dsa.h" unless $no_dsa; $crypto.=" crypto/dh/dh.h" unless $no_dh; $crypto.=" crypto/hmac/hmac.h" unless $no_hmac; -$crypto.=" crypto/dso/dso.h"; $crypto.=" crypto/engine/engine.h"; $crypto.=" crypto/stack/stack.h"; $crypto.=" crypto/buffer/buffer.h"; -- 2.25.1