File libgcrypt-FIPS-SLI-pk.patch of Package libgcrypt

Index: libgcrypt-1.9.4/src/fips.c
===================================================================
--- libgcrypt-1.9.4.orig/src/fips.c
+++ libgcrypt-1.9.4/src/fips.c
@@ -32,6 +32,7 @@
 
 #include "g10lib.h"
 #include "cipher-proto.h"
+#include "cipher.h"
 #include "hmac256.h"
 
 
@@ -482,6 +483,78 @@ _gcry_fips_indicator_kdf (va_list arg_pt
     default:
       return GPG_ERR_NOT_SUPPORTED;
     }
+}
+
+
+/* FIPS approved curves, extracted from:
+ *   cipher/ecc-curves.c:curve_aliases[] and domain_parms[]. */
+static const struct
+{
+  const char *name;  /* Our name.  */
+  const char *other; /* Other name. */
+} fips_approved_curve[] =
+  {
+    /* "NIST P-192" is non-approved if FIPS 140-3 */
+    /* { "NIST P-192", "1.2.840.10045.3.1.1" }, /\* X9.62 OID  *\/ */
+    /* { "NIST P-192", "prime192v1" },          /\* X9.62 name.  *\/ */
+    /* { "NIST P-192", "secp192r1"  },          /\* SECP name.  *\/ */
+    /* { "NIST P-192", "nistp192"   },          /\* rfc5656.  *\/ */
+
+    { "NIST P-224", "secp224r1" },
+    { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
+    { "NIST P-224", "nistp224"   },          /* rfc5656.  */
+
+    { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
+    { "NIST P-256", "prime256v1" },
+    { "NIST P-256", "secp256r1"  },
+    { "NIST P-256", "nistp256"   },          /* rfc5656.  */
+
+    { "NIST P-384", "secp384r1" },
+    { "NIST P-384", "1.3.132.0.34" },
+    { "NIST P-384", "nistp384"   },          /* rfc5656.  */
+
+    { "NIST P-521", "secp521r1" },
+    { "NIST P-521", "1.3.132.0.35" },
+    { "NIST P-521", "nistp521"   },          /* rfc5656.  */
+    { NULL, NULL}
+  };
+
+int
+_gcry_fips_indicator_pk (va_list arg_ptr)
+{
+  enum gcry_pk_algos alg = va_arg (arg_ptr, enum gcry_pk_algos);
+  enum pk_operation oper;
+  const char *curve_name;
+
+  switch (alg)
+    {
+    case GCRY_PK_RSA:
+    case GCRY_PK_RSA_E:
+    case GCRY_PK_RSA_S:
+      oper = va_arg (arg_ptr, enum pk_operation);
+      switch (oper)
+        {
+        case PUBKEY_OP_ENCRYPT:
+        case PUBKEY_OP_DECRYPT:
+          return GPG_ERR_NOT_SUPPORTED;
+        default:
+          return GPG_ERR_NO_ERROR;
+        }
+    case GCRY_PK_ECC:
+    case GCRY_PK_ECDH:
+    case GCRY_PK_ECDSA:
+      curve_name = va_arg (arg_ptr, const char *);
+      for (int idx = 0; fips_approved_curve[idx].name; ++idx)
+        {
+          /* Check for the usual name and an alias. */
+          if (!strcmp (curve_name, fips_approved_curve[idx].name) ||
+              !strcmp (curve_name, fips_approved_curve[idx].other))
+            return GPG_ERR_NO_ERROR;
+        }
+      return GPG_ERR_NOT_SUPPORTED;
+    default:
+      return GPG_ERR_NOT_SUPPORTED;
+    }
 }
 
 
Index: libgcrypt-1.9.4/src/gcrypt.h.in
===================================================================
--- libgcrypt-1.9.4.orig/src/gcrypt.h.in
+++ libgcrypt-1.9.4/src/gcrypt.h.in
@@ -336,7 +336,8 @@ enum gcry_ctl_cmds
     GCRYCTL_AUTO_EXPAND_SECMEM = 78,
     GCRYCTL_SET_ALLOW_WEAK_KEY = 79,
     GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81,
-    GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82
+    GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82,
+    GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83
   };
 
 /* Perform various operations defined by CMD. */
Index: libgcrypt-1.9.4/doc/gcrypt.texi
===================================================================
--- libgcrypt-1.9.4.orig/doc/gcrypt.texi
+++ libgcrypt-1.9.4/doc/gcrypt.texi
@@ -975,6 +975,18 @@ certification. If the KDF is approved, t
 @code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
 is returned.
 
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_PK; Arguments: enum gcry_pk_algos
+[, enum pk_operation (only for GCRY_PK_RSA)] [, const char * (only for
+GCRY_PK_ECC, GCRY_PK_ECDH or GCRY_PK_ECDSA)]
+
+Check if the given asymmetric cipher is approved under the current FIPS
+140-3 certification. For GCRY_PK_RSA, an additional parameter for the
+operation mode @code{enum pk_operation} is required. For GCRY_PK_ECC,
+GCRY_PK_ECDH and GCRY_PK_ECDSA, the additional parameter is the curve
+name or its alias as @code{const char *}. If the combination is
+approved, this function returns @code{GPG_ERR_NO_ERROR}. Otherwise
+@code{GPG_ERR_NOT_SUPPORTED} is returned.
+
 @end table
 
 @end deftypefun
Index: libgcrypt-1.9.4/src/g10lib.h
===================================================================
--- libgcrypt-1.9.4.orig/src/g10lib.h
+++ libgcrypt-1.9.4/src/g10lib.h
@@ -489,6 +489,7 @@ void _gcry_fips_signal_error (const char
 
 int _gcry_fips_indicator_cipher (va_list arg_ptr);
 int _gcry_fips_indicator_kdf (va_list arg_ptr);
+int _gcry_fips_indicator_pk (va_list arg_ptr);
 
 int _gcry_fips_is_operational (void);
 
Index: libgcrypt-1.9.4/src/global.c
===================================================================
--- libgcrypt-1.9.4.orig/src/global.c
+++ libgcrypt-1.9.4/src/global.c
@@ -768,6 +768,15 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
       rc = _gcry_fips_indicator_kdf (arg_ptr);
       break;
 
+    case GCRYCTL_FIPS_SERVICE_INDICATOR_PK:
+      /* Get FIPS Service Indicator for a given asymmetric algorithm. For
+       * GCRY_PK_RSA, an additional parameter for the operation mode is
+       * required. For ECC, ECDH and ECDSA, the additional parameter is the
+       * curve name or its alias. Returns GPG_ERR_NO_ERROR if the
+       * algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise. */
+      rc = _gcry_fips_indicator_pk (arg_ptr);
+      break;
+
     case PRIV_CTL_INIT_EXTRNG_TEST:  /* Init external random test.  */
       rc = GPG_ERR_NOT_SUPPORTED;
       break;
openSUSE Build Service is sponsored by