padlock: Reuse common CPU feature detection to check for Padlock features
authorMartin Willi <martin@revosec.ch>
Thu, 2 Apr 2015 12:05:39 +0000 (14:05 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 13 Apr 2015 13:31:58 +0000 (15:31 +0200)
src/libstrongswan/plugins/padlock/padlock_plugin.c

index 2005ef6..9ce2109 100644 (file)
 
 #include <library.h>
 #include <plugins/plugin_feature.h>
+#include <utils/cpu_feature.h>
 #include <utils/debug.h>
 
 typedef struct private_padlock_plugin_t private_padlock_plugin_t;
 typedef enum padlock_feature_t padlock_feature_t;
 
 /**
- * Feature flags of padlock, received via cpuid()
- */
-enum padlock_feature_t {
-       PADLOCK_RESERVED_1 =            (1<<0),
-       PADLOCK_RESERVED_2 =            (1<<1),
-       PADLOCK_RNG_AVAILABLE =         (1<<2),
-       PADLOCK_RNG_ENABLED =           (1<<3),
-       PADLOCK_RESERVED_3 =            (1<<4),
-       PADLOCK_RESERVED_4 =            (1<<5),
-       PADLOCK_ACE_AVAILABLE =         (1<<6),
-       PADLOCK_ACE_ENABLED =           (1<<7),
-       PADLOCK_ACE2_AVAILABLE =        (1<<8),
-       PADLOCK_ACE2_ENABLED =          (1<<9),
-       PADLOCK_PHE_AVAILABLE =         (1<<10),
-       PADLOCK_PHE_ENABLED =           (1<<11),
-       PADLOCK_PMM_AVAILABLE =         (1<<12),
-       PADLOCK_PMM_ENABLED =           (1<<13),
-};
-
-/**
  * private data of aes_plugin
  */
 struct private_padlock_plugin_t {
@@ -61,48 +42,9 @@ struct private_padlock_plugin_t {
        /**
         * features supported by Padlock
         */
-       padlock_feature_t features;
+       cpu_feature_t features;
 };
 
-/**
- * Get cpuid for info, return eax, ebx, ecx and edx. -fPIC requires to save ebx.
- */
-#define cpuid(op, a, b, c, d)\
-       asm (\
-               "pushl %%ebx            \n\t"\
-               "cpuid                          \n\t"\
-               "movl %%ebx, %1         \n\t"\
-               "popl %%ebx                     \n\t"\
-               : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
-               : "a" (op));
-
-/**
- * Get features supported by Padlock
- */
-static padlock_feature_t get_padlock_features()
-{
-       char vendor[3 * sizeof(int) + 1];
-       int a, b, c, d;
-
-       cpuid(0, a, b, c, d);
-       /* VendorID string is in b-d-c (yes, in this order) */
-       snprintf(vendor, sizeof(vendor), "%.4s%.4s%.4s", &b, &d, &c);
-
-       /* check if we have a VIA chip */
-       if (streq(vendor, "CentaurHauls"))
-       {
-               cpuid(0xC0000000, a, b, c, d);
-               /* check Centaur Extended Feature Flags */
-               if (a >= 0xC0000001)
-               {
-                       cpuid(0xC0000001, a, b, c, d);
-                       return d;
-               }
-       }
-       DBG1(DBG_LIB, "Padlock not found, CPU is %s", vendor);
-       return 0;
-}
-
 METHOD(plugin_t, get_name, char*,
        private_padlock_plugin_t *this)
 {
@@ -132,15 +74,15 @@ METHOD(plugin_t, get_features, int,
 
        if (!count)
        {       /* initialize only once */
-               if (this->features & PADLOCK_RNG_ENABLED)
+               if (this->features & CPU_FEATURE_PADLOCK_RNG_ENABLED)
                {
                        plugin_features_add(f, f_rng, countof(f_rng), &count);
                }
-               if (this->features & PADLOCK_ACE2_ENABLED)
+               if (this->features & CPU_FEATURE_PADLOCK_ACE2_ENABLED)
                {
                        plugin_features_add(f, f_aes, countof(f_aes), &count);
                }
-               if (this->features & PADLOCK_PHE_ENABLED)
+               if (this->features & CPU_FEATURE_PADLOCK_PHE_ENABLED)
                {
                        plugin_features_add(f, f_sha1, countof(f_sha1), &count);
                }
@@ -170,25 +112,20 @@ plugin_t *padlock_plugin_create()
                                .destroy = _destroy,
                        },
                },
-               .features = get_padlock_features(),
+               .features = cpu_feature_get_all(),
        );
 
-       if (!this->features)
-       {
-               free(this);
-               return NULL;
-       }
-       DBG1(DBG_LIB, "Padlock found, supports:%s%s%s%s%s, enabled:%s%s%s%s%s",
-                this->features & PADLOCK_RNG_AVAILABLE ? " RNG" : "",
-                this->features & PADLOCK_ACE_AVAILABLE ? " ACE" : "",
-                this->features & PADLOCK_ACE2_AVAILABLE ? " ACE2" : "",
-                this->features & PADLOCK_PHE_AVAILABLE ? " PHE" : "",
-                this->features & PADLOCK_PMM_AVAILABLE ? " PMM" : "",
-                this->features & PADLOCK_RNG_ENABLED ? " RNG" : "",
-                this->features & PADLOCK_ACE_ENABLED ? " ACE" : "",
-                this->features & PADLOCK_ACE2_ENABLED ? " ACE2" : "",
-                this->features & PADLOCK_PHE_ENABLED ? " PHE" : "",
-                this->features & PADLOCK_PMM_ENABLED ? " PMM" : "");
+       DBG1(DBG_LIB, "Padlock features supported:%s%s%s%s%s, enabled:%s%s%s%s%s",
+                this->features & CPU_FEATURE_PADLOCK_RNG_AVAILABLE ? " RNG" : "",
+                this->features & CPU_FEATURE_PADLOCK_ACE_AVAILABLE ? " ACE" : "",
+                this->features & CPU_FEATURE_PADLOCK_ACE2_AVAILABLE ? " ACE2" : "",
+                this->features & CPU_FEATURE_PADLOCK_PHE_AVAILABLE ? " PHE" : "",
+                this->features & CPU_FEATURE_PADLOCK_PMM_AVAILABLE ? " PMM" : "",
+                this->features & CPU_FEATURE_PADLOCK_RNG_ENABLED ? " RNG" : "",
+                this->features & CPU_FEATURE_PADLOCK_ACE_ENABLED ? " ACE" : "",
+                this->features & CPU_FEATURE_PADLOCK_ACE2_ENABLED ? " ACE2" : "",
+                this->features & CPU_FEATURE_PADLOCK_PHE_ENABLED ? " PHE" : "",
+                this->features & CPU_FEATURE_PADLOCK_PMM_ENABLED ? " PMM" : "");
 
        return &this->public.plugin;
 }