Sanity check provider up-calls
[openssl.git] / providers / common / provider_seeding.c
index 98704a2cdf36a0b1d84bef3344ba9dd545f71d39..73a2a1418742d7cefa1e6da51291f30db3b6e3b0 100644 (file)
@@ -18,22 +18,24 @@ static OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL;
 int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
 {
     for (; fns->function_id != 0; fns++) {
+        /*
+         * We do not support the scenario of an application linked against
+         * multiple versions of libcrypto (e.g. one static and one dynamic), but
+         * sharing a single fips.so. We do a simple sanity check here.
+         */
+#define set_func(c, f) if (c == NULL) c = f; else if (c != f) return 0;
         switch (fns->function_id) {
         case OSSL_FUNC_GET_ENTROPY:
-            if (c_get_entropy == NULL)
-                c_get_entropy = OSSL_FUNC_get_entropy(fns);
+            set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns));
             break;
         case OSSL_FUNC_CLEANUP_ENTROPY:
-            if (c_cleanup_entropy == NULL)
-                c_cleanup_entropy = OSSL_FUNC_cleanup_entropy(fns);
+            set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns));
             break;
         case OSSL_FUNC_GET_NONCE:
-            if (c_get_nonce == NULL)
-                c_get_nonce = OSSL_FUNC_get_nonce(fns);
+            set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns));
             break;
         case OSSL_FUNC_CLEANUP_NONCE:
-            if (c_cleanup_nonce == NULL)
-                c_cleanup_nonce = OSSL_FUNC_cleanup_nonce(fns);
+            set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns));
             break;
         }
     }