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)
                {

Reply via email to