FIPS provider modifications
authorDmitry Belyavskiy <beldmit@gmail.com>
Wed, 13 Apr 2022 10:33:21 +0000 (12:33 +0200)
committerDmitry Belyavskiy <beldmit@gmail.com>
Thu, 21 Apr 2022 15:12:31 +0000 (17:12 +0200)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18103)

providers/fips/fipsprov.c

index f4605dcd6ce5f44a65ba6e04c158ff73d7aa29b7..fc17a958ce269afc269942ea31ab940208e65ced 100644 (file)
@@ -22,6 +22,7 @@
 #include "prov/provider_util.h"
 #include "prov/seeding.h"
 #include "self_test.h"
+#include "internal/core.h"
 
 static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes";
 static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no";
@@ -35,6 +36,22 @@ static OSSL_FUNC_provider_gettable_params_fn fips_gettable_params;
 static OSSL_FUNC_provider_get_params_fn fips_get_params;
 static OSSL_FUNC_provider_query_operation_fn fips_query;
 
+/* Locale object accessor functions */
+#ifdef OPENSSL_SYS_MACOSX
+# include <xlocale.h>
+#else
+# include <locale.h>
+#endif
+
+#if defined OPENSSL_SYS_WINDOWS
+# define locale_t _locale_t
+# define freelocale _free_locale
+#endif
+static locale_t loc;
+
+static int fips_init_casecmp(void);
+static void fips_deinit_casecmp(void);
+
 #define ALGC(NAMES, FUNC, CHECK) { { NAMES, FIPS_DEFAULT_PROPERTIES, FUNC }, CHECK }
 #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
 
@@ -486,6 +503,23 @@ static const OSSL_ALGORITHM *fips_query(void *provctx, int operation_id,
     return NULL;
 }
 
+void *ossl_c_locale() {
+    return (void *)loc;
+}
+
+static int fips_init_casecmp(void) {
+# ifdef OPENSSL_SYS_WINDOWS
+    loc = _create_locale(LC_COLLATE, "C");
+# else
+    loc = newlocale(LC_COLLATE_MASK, "C", (locale_t) 0);
+# endif
+    return (loc == (locale_t) 0) ? 0 : 1;
+}
+
+static void fips_deinit_casecmp(void) {
+    freelocale(loc);
+}
+
 static void fips_teardown(void *provctx)
 {
     OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx));
@@ -498,6 +532,7 @@ static void fips_intern_teardown(void *provctx)
      * We know that the library context is the same as for the outer provider,
      * so no need to destroy it here.
      */
+    fips_deinit_casecmp();
     ossl_prov_ctx_free(provctx);
 }
 
@@ -547,6 +582,8 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
 
     memset(&selftest_params, 0, sizeof(selftest_params));
 
+    if (!fips_init_casecmp())
+        return 0;
     if (!ossl_prov_seeding_from_dispatch(in))
         return 0;
     for (; in->function_id != 0; in++) {