Currently, ENGINE_load_rdrand will clear the error queue if the engine
is loaded; but ENGINE_load_rdrand fails to set an error code if RDRAND
is not available.

This patch adds a check with an appropriate error code so callers can
check for failure.

Note: crypto/engine/engine.h only provides a define for
ENGINE_F_ENGINE_INIT. There is no define for LOAD (only INIT). Also,
ENGINE_R_NO_SUCH_ENGINE seemed like the best choice when the hardware
does not offer RDRAND. Other choices appear to include
ENGINE_R_INIT_FAILED, but that might overlap with an error returned
from ENGINE_add.

diff --git a/crypto/engine/eng_rdrand.c b/crypto/engine/eng_rdrand.c
index 4e9e91d..09616b7 100644
--- a/crypto/engine/eng_rdrand.c
+++ b/crypto/engine/eng_rdrand.c
@@ -129,14 +129,17 @@ void ENGINE_load_rdrand (void)
        {
        extern unsigned int OPENSSL_ia32cap_P[];

-       if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
+       if(!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
                {
-               ENGINE *toadd = ENGINE_rdrand();
-               if(!toadd) return;
-               ENGINE_add(toadd);
-               ENGINE_free(toadd);
-               ERR_clear_error();
+               ENGINEerr(ENGINE_F_ENGINE_INIT, ENGINE_R_NO_SUCH_ENGINE);
+               return;
                }
+
+    ENGINE *toadd = ENGINE_rdrand();
+    if(!toadd) return;
+    ENGINE_add(toadd);
+    ENGINE_free(toadd);
+    ERR_clear_error();
        }
 #else
 void ENGINE_load_rdrand (void) {}

diff --git a/crypto/engine/eng_rdrand.c b/crypto/engine/eng_rdrand.c
index 4e9e91d..09616b7 100644
--- a/crypto/engine/eng_rdrand.c
+++ b/crypto/engine/eng_rdrand.c
@@ -129,14 +129,17 @@ void ENGINE_load_rdrand (void)
        {
        extern unsigned int OPENSSL_ia32cap_P[];
 
-       if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
+       if(!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
                {
-               ENGINE *toadd = ENGINE_rdrand();
-               if(!toadd) return;
-               ENGINE_add(toadd);
-               ENGINE_free(toadd);
-               ERR_clear_error();
+               ENGINEerr(ENGINE_F_ENGINE_INIT, ENGINE_R_NO_SUCH_ENGINE);
+               return;
                }
+
+    ENGINE *toadd = ENGINE_rdrand();
+    if(!toadd) return;
+    ENGINE_add(toadd);
+    ENGINE_free(toadd);
+    ERR_clear_error();
        }
 #else
 void ENGINE_load_rdrand (void) {}

Reply via email to