Browse Source

linuxkm/linuxkm_memory.c: fix circular dependency around wolfCrypt_Init(), allocate_wolfcrypt_linuxkm_fpu_states(), wc_linuxkm_fpu_state_assoc(), on FIPS.

Daniel Pouzzner 3 weeks ago
parent
commit
326fd87b4f
1 changed files with 53 additions and 10 deletions
  1. 53 10
      linuxkm/linuxkm_memory.c

+ 53 - 10
linuxkm/linuxkm_memory.c

@@ -116,6 +116,10 @@ static union wc_linuxkm_fpu_savebuf {
 WARN_UNUSED_RESULT int allocate_wolfcrypt_linuxkm_fpu_states(void)
 {
     if (wc_linuxkm_fpu_states != NULL) {
+#ifdef HAVE_FIPS
+        /* see note below in wc_linuxkm_fpu_state_assoc_unlikely(). */
+        return 0;
+#else
         static int warned_for_repeat_alloc = 0;
         if (! warned_for_repeat_alloc) {
             pr_err("attempt at repeat allocation"
@@ -123,6 +127,7 @@ WARN_UNUSED_RESULT int allocate_wolfcrypt_linuxkm_fpu_states(void)
             warned_for_repeat_alloc = 1;
         }
         return BAD_STATE_E;
+#endif
     }
 
 #ifdef LINUXKM_FPU_STATES_FOLLOW_THREADS
@@ -225,12 +230,25 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc(int create_p)
         static int _warned_on_null = 0;
         if (wc_linuxkm_fpu_states == NULL)
         {
-            if (_warned_on_null == 0) {
-                pr_err("wc_linuxkm_fpu_state_assoc called by pid %d"
-                       " before allocate_wolfcrypt_linuxkm_fpu_states.\n", my_pid);
-                _warned_on_null = 1;
+#ifdef HAVE_FIPS
+            /* FIPS needs to use SHA256 for the core verify HMAC, before
+             * reaching the regular wolfCrypt_Init() logic.  to break the
+             * dependency loop on intelasm builds, we allocate here.
+             * this is not thread-safe and doesn't need to be.
+             */
+            int ret = allocate_wolfcrypt_linuxkm_fpu_states();
+            if (ret == 0) {
+            }
+            else
+#endif
+            {
+                if (_warned_on_null == 0) {
+                    pr_err("wc_linuxkm_fpu_state_assoc called by pid %d"
+                           " before allocate_wolfcrypt_linuxkm_fpu_states.\n", my_pid);
+                    _warned_on_null = 1;
+                }
+                return NULL;
             }
-            return NULL;
         }
     }
 
@@ -282,12 +300,25 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c
         static int _warned_on_null = 0;
         if (wc_linuxkm_fpu_states == NULL)
         {
-            if (_warned_on_null == 0) {
-                pr_err("wc_linuxkm_fpu_state_assoc called by pid %d"
-                       " before allocate_wolfcrypt_linuxkm_fpu_states.\n", my_pid);
-                _warned_on_null = 1;
+#ifdef HAVE_FIPS
+            /* FIPS needs to use SHA256 for the core verify HMAC, before
+             * reaching the regular wolfCrypt_Init() logic.  to break the
+             * dependency loop on intelasm builds, we allocate here.
+             * this is not thread-safe and doesn't need to be.
+             */
+            int ret = allocate_wolfcrypt_linuxkm_fpu_states();
+            if (ret == 0) {
+            }
+            else
+#endif
+            {
+                if (_warned_on_null == 0) {
+                    pr_err("wc_linuxkm_fpu_state_assoc called by pid %d"
+                           " before allocate_wolfcrypt_linuxkm_fpu_states.\n", my_pid);
+                    _warned_on_null = 1;
+                }
+                return NULL;
             }
-            return NULL;
         }
     }
 
@@ -419,6 +450,18 @@ static inline void wc_linuxkm_fpu_state_release(
     __atomic_store_n(&ent->pid, 0, __ATOMIC_RELEASE);
 }
 
+WARN_UNUSED_RESULT int can_save_vector_registers_x86(void)
+{
+    if (irq_fpu_usable())
+        return 1;
+    else if (in_nmi() || (hardirq_count() > 0) || (softirq_count() > 0))
+        return 0;
+    else if (test_thread_flag(TIF_NEED_FPU_LOAD))
+        return 1;
+    else
+        return 0;
+}
+
 WARN_UNUSED_RESULT int save_vector_registers_x86(void)
 {
 #ifdef LINUXKM_FPU_STATES_FOLLOW_THREADS