{"action":"created","issue":{"url":"https://api.github.com/repos/opendnssec/SoftHSMv2/issues/386","repository_url":"https://api.github.com/repos/opendnssec/SoftHSMv2","labels_url":"https://api.github.com/repos/opendnssec/SoftHSMv2/issues/386/labels{/name}","comments_url":"https://api.github.com/repos/opendnssec/SoftHSMv2/issues/386/comments","events_url":"https://api.github.com/repos/opendnssec/SoftHSMv2/issues/386/events","html_url":"https://github.com/opendnssec/SoftHSMv2/issues/386","id":311412134,"number":386,"title":"SoftHSMv2 gets into infinite recursion over RNG","user":{"login":"mouse07410","id":5923577,"avatar_url":"https://avatars1.githubusercontent.com/u/5923577?v=4","gravatar_id":"","url":"https://api.github.com/users/mouse07410","html_url":"https://github.com/mouse07410","followers_url":"https://api.github.com/users/mouse07410/followers","following_url":"https://api.github.com/users/mouse07410/following{/other_user}","gists_url":"https://api.github.com/users/mouse07410/gists{/gist_id}","starred_url":"https://api.github.com/users/mouse07410/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mouse07410/subscriptions","organizations_url":"https://api.github.com/users/mouse07410/orgs","repos_url":"https://api.github.com/users/mouse07410/repos","events_url":"https://api.github.com/users/mouse07410/events{/privacy}","received_events_url":"https://api.github.com/users/mouse07410/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2018-04-04T22:25:43Z","updated_at":"2018-04-23T13:55:33Z","closed_at":null,"author_association":"NONE","body":"The problem surfaced with the addition of support for [PKCS#11 random number generator in libp11](https://github.com/OpenSC/libp11/pull/214). This is on MacOS Sierra and High Sierra, using OpenSSL-1.0.2o (installed via Macports, but that shouldn't matter).\r\n\r\nWhat happens is that SoftHSMv2 gets into infinite recursion - soft token initialization requires getting random numbers that in turn requires soft token initialization... Like this:\r\n```\r\nSampling process 20624 for 3 seconds with 1 millisecond of run time between samples\r\nSampling completed, processing symbols...\r\nAnalysis of sampling evp-sign (pid 20624) every 1 millisecond\r\nProcess:         evp-sign [20624]\r\nPath:            /Users/ur20980/src/libp11/tests/.libs/evp-sign\r\nLoad Address:    0x10402a000\r\nIdentifier:      evp-sign\r\nVersion:         0\r\nCode Type:       X86-64\r\nParent Process:  sh [20612]\r\n\r\nDate/Time:       2018-04-04 13:25:08.525 -0400\r\nLaunch Time:     2018-04-04 13:23:37.908 -0400\r\nOS Version:      Mac OS X 10.12.6 (16G1314)\r\nReport Version:  7\r\nAnalysis Tool:   /usr/bin/sample\r\n----\r\n\r\nCall graph:\r\n    2447 Thread_4137815   DispatchQueue_1: com.apple.main-thread  (serial)\r\n      1829 OSSLRNG::generateRandom(ByteString&, unsigned long)  (in libsofthsm2.so) + 49  [0x1043d8ca1]\r\n      + 1829 RAND_bytes  (in libcrypto.1.0.0.dylib) + 60  [0x10416183c]\r\n      +   1829 engine_table_select  (in libcrypto.1.0.0.dylib) + 267  [0x1041511ab]\r\n      +     1829 engine_unlocked_init  (in libcrypto.1.0.0.dylib) + 59  [0x1041501eb]\r\n      +       1829 ctx_init  (in libpkcs11.dylib) + 86  [0x1043647f6]\r\n      +         1829 ctx_init_libp11_unlocked  (in libpkcs11.dylib) + 96  [0x104364890]\r\n      +           1829 pkcs11_CTX_load  (in libpkcs11.dylib) + 101  [0x1043699c5]\r\n      +             1829 C_Initialize  (in libsofthsm2.so) + 25  [0x104378909]\r\n      +               1829 SoftHSM::C_Initialize(void*)  (in libsofthsm2.so) + 994  [0x1043922e2]\r\n      +                 1829 SlotManager::SlotManager(ObjectStore*)  (in libsofthsm2.so) + 506  [0x10440529a]\r\n      +                   1829 SlotManager::insertToken(ObjectStore*, unsigned long, ObjectStoreToken*)  (in libsofthsm2.so) + 56  [0x1044053f8]\r\n      +                     1829 Slot::Slot(ObjectStore*, unsigned long, ObjectStoreToken*)  (in libsofthsm2.so) + 63  [0x104405f7f]\r\n      +                       1829 Token::Token(ObjectStoreToken*)  (in libsofthsm2.so) + 136  [0x1044066e8]\r\n      +                         1829 SecureDataManager::SecureDataManager(ByteString const&, ByteString const&)  (in libsofthsm2.so) + 86  [0x1043e1a06]\r\n      +                           1829 SecureDataManager::initObject()  (in libsofthsm2.so) + 114  [0x1043e16d2]\r\n      +                             1829 OSSLRNG::generateRandom(ByteString&, unsigned long)  (in libsofthsm2.so) + 49  [0x1043d8ca1]\r\n      +                               1829 RAND_bytes  (in libcrypto.1.0.0.dylib) + 60  [0x10416183c]\r\n      +                                 1829 engine_table_select  (in libcrypto.1.0.0.dylib) + 267  [0x1041511ab]\r\n      +                                   1829 engine_unlocked_init  (in libcrypto.1.0.0.dylib) + 59  [0x1041501eb]\r\n      +                                     1829 ctx_init  (in libpkcs11.dylib) + 86  [0x1043647f6]\r\n      +                                       1829 ctx_init_libp11_unlocked  (in libpkcs11.dylib) + 96  [0x104364890]\r\n      +                                         1829 pkcs11_CTX_load  (in libpkcs11.dylib) + 101  [0x1043699c5]\r\n      +                                           1829 C_Initialize  (in libsofthsm2.so) + 25  [0x104378909]\r\n      +                                             1829 SoftHSM::C_Initialize(void*)  (in libsofthsm2.so) + 994  [0x1043922e2]\r\n      +                                               1829 SlotManager::SlotManager(ObjectStore*)  (in libsofthsm2.so) + 506  [0x10440529a]\r\n      +                                                 1829 SlotManager::insertToken(ObjectStore*, unsigned long, ObjectStoreToken*)  (in libsofthsm2.so) + 56  [0x1044053f8]\r\n      +                                                   1829 Slot::Slot(ObjectStore*, unsigned long, ObjectStoreToken*)  (in libsofthsm2.so) + 63  [0x104405f7f]\r\n      +                                                     1829 Token::Token(ObjectStoreToken*)  (in libsofthsm2.so) + 136  [0x1044066e8]\r\n      +                                                       1829 SecureDataManager::SecureDataManager(ByteString const&, ByteString const&)  (in libsofthsm2.so) + 86  [0x1043e1a06]\r\n      +                                                         1829 SecureDataManager::initObject()  (in libsofthsm2.so) + 114  [0x1043e16d2]\r\n      +                                                           1829 OSSLRNG::generateRandom(ByteString&, unsigned long)  (in libsofthsm2.so) + 49  [0x1043d8ca1]\r\n      +                                                             1829 RAND_bytes  (in libcrypto.1.0.0.dylib) + 60  [0x10416183c]\r\n      +                                                               1829 engine_table_select  (in libcrypto.1.0.0.dylib) + 267  [0x1041511ab]\r\n      +                                                                 1829 engine_unlocked_init  (in libcrypto.1.0.0.dylib) + 59  [0x1041501eb]\r\n      +                                                                   1829 ctx_init  (in libpkcs11.dylib) + 86  [0x1043647f6]\r\n      +                                                                     1829 ctx_init_libp11_unlocked  (in libpkcs11.dylib) + 96  [0x104364890]\r\n      +                                                                       1829 pkcs11_CTX_load  (in libpkcs11.dylib) + 101  [0x1043699c5]\r\n      +                                                                         1829 C_Initialize  (in libsofthsm2.so) + 25  [0x104378909]\r\n      +                                                                           1829 SoftHSM::C_Initialize(void*)  (in libsofthsm2.so) + 994  [0x1043922e2]\r\n. . . . .\r\n```\r\n\r\nReposting the full process sample here: \r\n[Sample of evp-sign-2.txt](https://github.com/opendnssec/SoftHSMv2/files/1877940/Sample.of.evp-sign-2.txt)\r\n\r\nSetting RDRAND as the default RAND provider resolves this issue, so this is one potential solution you might consider. I made it so that if RDRAND engine is not available for whatever reason, then the code just falls back to the current (bad) behavior.\r\n```\r\ndiff --git a/src/lib/crypto/OSSLCryptoFactory.cpp b/src/lib/crypto/OSSLCryptoFactory.cpp\r\nindex 8555815..c9cd318 100644\r\n--- a/src/lib/crypto/OSSLCryptoFactory.cpp\r\n+++ b/src/lib/crypto/OSSLCryptoFactory.cpp\r\n@@ -137,10 +137,27 @@ OSSLCryptoFactory::OSSLCryptoFactory()\r\n        }\r\n        FipsSelfTestStatus = true;\r\n #endif\r\n-\r\n        // Initialise OpenSSL\r\n        OpenSSL_add_all_algorithms();\r\n \r\n+       // Make sure RDRAND is loaded first\r\n+       ENGINE_load_rdrand();\r\n+       // Locate the engine\r\n+       rdrand_engine = ENGINE_by_id(\"rdrand\");\r\n+       if ( rdrand_engine == NULL ) {\r\n+               fprintf(stderr, \"ENGINE_load_rdrand returned %lu\\n\", ERR_get_error());\r\n+       }\r\n+       // Initialize RDRAND engine\r\n+       if ( ! ENGINE_init(rdrand_engine) ) {\r\n+               fprintf(stderr, \"ENGINE_init returned %lu\\n\", ERR_get_error());\r\n+       }\r\n+       // Seet RDRAND engine as the default for RAND_ methods\r\n+       if ( ! ENGINE_set_default(rdrand_engine, ENGINE_METHOD_RAND) ) {\r\n+               fprintf(stderr, \"ENGINE_set_default returned %lu\\n\", ERR_get_error());\r\n+       }\r\n+\r\n+\r\n+\r\n        // Initialise the one-and-only RNG\r\n        rng = new OSSLRNG();\r\n \r\n@@ -150,6 +167,10 @@ OSSLCryptoFactory::OSSLCryptoFactory()\r\n        ENGINE_load_builtin_engines();\r\n #else\r\n        OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN |\r\n+                           OPENSSL_INIT_ENGINE_RDRAND |\r\n+                           OPENSSL_INIT_LOAD_CRYPTO_STRINGS |\r\n+                           OPENSSL_INIT_ADD_ALL_CIPHERS |\r\n+                           OPENSSL_INIT_ADD_ALL_DIGESTS |\r\n                            OPENSSL_INIT_LOAD_CONFIG, NULL);\r\n #endif\r\n \r\ndiff --git a/src/lib/crypto/OSSLCryptoFactory.h b/src/lib/crypto/OSSLCryptoFactory.h\r\nindex e8bfa2c..8dfb128 100644\r\n--- a/src/lib/crypto/OSSLCryptoFactory.h\r\n+++ b/src/lib/crypto/OSSLCryptoFactory.h\r\n@@ -105,6 +105,8 @@ private:\r\n \r\n        // The one-and-only RNG instance\r\n        RNG* rng;\r\n+       // And RDRAND engine to use with it\r\n+       ENGINE *rdrand_engine;\r\n \r\n #ifdef WITH_GOST\r\n        // The GOST engine\r\n```\r\n\r\nI'd be happy for other solutions as well, as long as you get rid of this recursion. But one thing is clear - you cannot use the same pkcs11 engine as the one you're trying to load."},"comment":{"url":"https://api.github.com/repos/opendnssec/SoftHSMv2/issues/comments/383583943","html_url":"https://github.com/opendnssec/SoftHSMv2/issues/386#issuecomment-383583943","issue_url":"https://api.github.com/repos/opendnssec/SoftHSMv2/issues/386","id":383583943,"user":{"login":"mouse07410","id":5923577,"avatar_url":"https://avatars1.githubusercontent.com/u/5923577?v=4","gravatar_id":"","url":"https://api.github.com/users/mouse07410","html_url":"https://github.com/mouse07410","followers_url":"https://api.github.com/users/mouse07410/followers","following_url":"https://api.github.com/users/mouse07410/following{/other_user}","gists_url":"https://api.github.com/users/mouse07410/gists{/gist_id}","starred_url":"https://api.github.com/users/mouse07410/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mouse07410/subscriptions","organizations_url":"https://api.github.com/users/mouse07410/orgs","repos_url":"https://api.github.com/users/mouse07410/repos","events_url":"https://api.github.com/users/mouse07410/events{/privacy}","received_events_url":"https://api.github.com/users/mouse07410/received_events","type":"User","site_admin":false},"created_at":"2018-04-23T13:55:33Z","updated_at":"2018-04-23T13:55:33Z","author_association":"NONE","body":"> Why use OpenSSL-depent SoftHSMv2 with a PKCS#11 engine in OpenSSL...\r\n\r\nFirst - for testing. libp11 tests are designed around SoftHSMv2. Second - for applications and scripts that expect a PKCS#11 crypto device. I want them to run unmodified (just point to the right PKCS#11 library) regardless of what kind of token I'm dealing with. Finally, as I reported elsewhere, if I try to use libp11 with SoftHSMv2 that's configured with Botan instead of OpenSSL, if always crashes."}}
{"actor":{"display_login":"mouse07410"}}