Hi,
It appears the logic in OpenSSL 0.9.8 for caching the default engine for a
given algorithm is inverted. Specifically, the "uptodate" flag in
crypto/engine/eng_table.c is written to in three places with the opposite
sense to what its name and comment implies. It is read from and written to
once elsewhere with the correct sense.
The effect is that loaded engines are not used unless specifically
requested, contrary to the behaviour described under "Automatically using
builtin ENGINE implementations" in the documentation at:
http://www.openssl.org/docs/crypto/engine.html#Application_requirements
I believe the code was written correctly in the original revision 1.1
(checkin 5270) and is correct in all releases of OpenSSL 0.9.7 but was
incorrectly "fixed" in revision 1.6 (checkin 12358) and shipped broken in
all releases of OpenSSL 0.9.8. The attached patch restores the original
behaviour.
The symptom that led me to this was that OpenSSH 5.0p1 (and earlier) was
not getting any benefit of hardware acceleration when running on a VIA C7
(with its Padlock hardware) and FreeBSD 7.0 (with OpenSSL 0.9.8e). The
same machine had previously seen accelerated encryption when running
FreeBSD 6.2 (with OpenSSL 0.9.7e-p1). Modifying OpenSSH to add a call to
ENGINE_set_default_ciphers to explicitly request the Padlock engine be
used (via ENGINE_set_default_ciphers) worked around the issue. Applying
the attached patch fixes it directly. For more background see the bug
report at:
https://bugs.launchpad.net/bugs/119295
Thanks also to John Steele Scott for his work on the issue.
Regards,
Ian
--- openssl-0.9.8g/crypto/engine/eng_table.c 2007-09-06 22:43:49.000000000
+1000
+++ openssl-0.9.8g-uptodate/crypto/engine/eng_table.c 2008-04-22
18:24:01.000000000 +1000
@@ -135,7 +135,7 @@
{
fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
if(!fnd) goto end;
- fnd->uptodate = 0;
+ fnd->uptodate = 1;
fnd->nid = *nids;
fnd->sk = sk_ENGINE_new_null();
if(!fnd->sk)
@@ -152,7 +152,7 @@
if(!sk_ENGINE_push(fnd->sk, e))
goto end;
/* "touch" this ENGINE_PILE */
- fnd->uptodate = 1;
+ fnd->uptodate = 0;
if(setdefault)
{
if(!engine_unlocked_init(e))
@@ -180,7 +180,7 @@
{
(void)sk_ENGINE_delete(pile->sk, n);
/* "touch" this ENGINE_CIPHER */
- pile->uptodate = 1;
+ pile->uptodate = 0;
}
if(pile->funct == e)
{