Blame SOURCES/libgcrypt-1.8.3-cmac-selftest.patch

66e42d
diff -up libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest libgcrypt-1.8.3/cipher/cipher-cmac.c
66e42d
--- libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest	2017-11-23 19:16:58.000000000 +0100
66e42d
+++ libgcrypt-1.8.3/cipher/cipher-cmac.c	2019-05-31 17:33:35.594407152 +0200
66e42d
@@ -251,3 +251,246 @@ _gcry_cipher_cmac_set_subkeys (gcry_ciph
66e42d
 
66e42d
   return GPG_ERR_NO_ERROR;
66e42d
 }
66e42d
+
66e42d
+/* CMAC selftests.
66e42d
+ * Copyright (C) 2008 Free Software Foundation, Inc.
66e42d
+ * Copyright (C) 2019 Red Hat, Inc.
66e42d
+ */
66e42d
+
66e42d
+
66e42d
+
66e42d
+/* Check one MAC with MAC ALGO using the regular MAC
66e42d
+ * API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
66e42d
+ * and (EXPECT,EXPECTLEN) the expected result.  If TRUNC is set, the
66e42d
+ * EXPECTLEN may be less than the digest length.  Returns NULL on
66e42d
+ * success or a string describing the failure.  */
66e42d
+static const char *
66e42d
+check_one (int algo,
66e42d
+           const void *data, size_t datalen,
66e42d
+           const void *key, size_t keylen,
66e42d
+           const void *expect, size_t expectlen)
66e42d
+{
66e42d
+  gcry_mac_hd_t hd;
66e42d
+  unsigned char mac[512]; /* hardcoded to avoid allocation */
66e42d
+  size_t macoutlen = expectlen;
66e42d
+
66e42d
+/*   printf ("MAC algo %d\n", algo); */
66e42d
+  if (_gcry_mac_get_algo_maclen (algo) != expectlen ||
66e42d
+      expectlen > sizeof (mac))
66e42d
+    return "invalid tests data";
66e42d
+  if (_gcry_mac_open (&hd, algo, 0, NULL))
66e42d
+    return "gcry_mac_open failed";
66e42d
+  if (_gcry_mac_setkey (hd, key, keylen))
66e42d
+    {
66e42d
+      _gcry_mac_close (hd);
66e42d
+      return "gcry_md_setkey failed";
66e42d
+    }
66e42d
+  if (_gcry_mac_write (hd, data, datalen))
66e42d
+    {
66e42d
+      _gcry_mac_close (hd);
66e42d
+      return "gcry_mac_write failed";
66e42d
+    }
66e42d
+  if (_gcry_mac_read (hd, mac, &macoutlen))
66e42d
+    {
66e42d
+      _gcry_mac_close (hd);
66e42d
+      return "gcry_mac_read failed";
66e42d
+    }
66e42d
+  _gcry_mac_close (hd);
66e42d
+  if (macoutlen != expectlen || memcmp (mac, expect, expectlen))
66e42d
+    {
66e42d
+/*       int i; */
66e42d
+
66e42d
+/*       fputs ("        {", stdout); */
66e42d
+/*       for (i=0; i < expectlen-1; i++) */
66e42d
+/*         { */
66e42d
+/*           if (i && !(i % 8)) */
66e42d
+/*             fputs ("\n         ", stdout); */
66e42d
+/*           printf (" 0x%02x,", mac[i]); */
66e42d
+/*         } */
66e42d
+/*       printf (" 0x%02x } },\n", mac[i]); */
66e42d
+
66e42d
+      return "does not match";
66e42d
+    }
66e42d
+  return NULL;
66e42d
+}
66e42d
+
66e42d
+
66e42d
+static gpg_err_code_t
66e42d
+selftests_cmac_tdes (int extended, selftest_report_func_t report)
66e42d
+{
66e42d
+  const char *what;
66e42d
+  const char *errtxt;
66e42d
+
66e42d
+  what = "Basic TDES";
66e42d
+  errtxt = check_one (GCRY_MAC_CMAC_3DES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
66e42d
+        "\xae\x2d\x8a\x57", 20,
66e42d
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
66e42d
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24,
66e42d
+        "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed", 8);
66e42d
+  if (errtxt)
66e42d
+    goto failed;
66e42d
+
66e42d
+  if (extended)
66e42d
+    {
66e42d
+      what = "Extended TDES #1";
66e42d
+      errtxt = check_one (GCRY_MAC_CMAC_3DES,
66e42d
+        "", 0,
66e42d
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
66e42d
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24,
66e42d
+        "\xb7\xa6\x88\xe1\x22\xff\xaf\x95", 8);
66e42d
+      if (errtxt)
66e42d
+        goto failed;
66e42d
+
66e42d
+      what = "Extended TDES #2";
66e42d
+      errtxt = check_one (GCRY_MAC_CMAC_3DES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96", 8,
66e42d
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
66e42d
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24,
66e42d
+        "\x8e\x8f\x29\x31\x36\x28\x37\x97", 8);
66e42d
+      if (errtxt)
66e42d
+        goto failed;
66e42d
+
66e42d
+      what = "Extended TDES #3";
66e42d
+      errtxt = check_one (GCRY_MAC_CMAC_3DES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
66e42d
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 32,
66e42d
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
66e42d
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24,
66e42d
+        "\x33\xe6\xb1\x09\x24\x00\xea\xe5", 8);
66e42d
+      if (errtxt)
66e42d
+        goto failed;
66e42d
+    }
66e42d
+
66e42d
+  return 0; /* Succeeded. */
66e42d
+
66e42d
+ failed:
66e42d
+  if (report)
66e42d
+    report ("cmac", GCRY_MAC_CMAC_3DES, what, errtxt);
66e42d
+  return GPG_ERR_SELFTEST_FAILED;
66e42d
+}
66e42d
+
66e42d
+
66e42d
+
66e42d
+static gpg_err_code_t
66e42d
+selftests_cmac_aes (int extended, selftest_report_func_t report)
66e42d
+{
66e42d
+  const char *what;
66e42d
+  const char *errtxt;
66e42d
+
66e42d
+  what = "Basic AES128";
66e42d
+  errtxt = check_one (GCRY_MAC_CMAC_AES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
66e42d
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
66e42d
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40,
66e42d
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16,
66e42d
+        "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27", 16);
66e42d
+  if (errtxt)
66e42d
+    goto failed;
66e42d
+
66e42d
+  what = "Basic AES192";
66e42d
+  errtxt = check_one (GCRY_MAC_CMAC_AES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
66e42d
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
66e42d
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40,
66e42d
+        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
66e42d
+        "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24,
66e42d
+        "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e", 16);
66e42d
+  if (errtxt)
66e42d
+    goto failed;
66e42d
+
66e42d
+  what = "Basic AES256";
66e42d
+  errtxt = check_one (GCRY_MAC_CMAC_AES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
66e42d
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
66e42d
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40,
66e42d
+        "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
66e42d
+        "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32,
66e42d
+        "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6", 16);
66e42d
+  if (errtxt)
66e42d
+    goto failed;
66e42d
+  if (extended)
66e42d
+    {
66e42d
+      what = "Extended AES #1";
66e42d
+      errtxt = check_one (GCRY_MAC_CMAC_AES,
66e42d
+        "", 0,
66e42d
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16,
66e42d
+        "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46", 16);
66e42d
+      if (errtxt)
66e42d
+        goto failed;
66e42d
+
66e42d
+      what = "Extended AES #2";
66e42d
+      errtxt = check_one (GCRY_MAC_CMAC_AES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16,
66e42d
+        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
66e42d
+        "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24,
66e42d
+        "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84", 16);
66e42d
+      if (errtxt)
66e42d
+        goto failed;
66e42d
+
66e42d
+      what = "Extended AES #3";
66e42d
+      errtxt = check_one (GCRY_MAC_CMAC_AES,
66e42d
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
66e42d
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
66e42d
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
66e42d
+        "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64,
66e42d
+        "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
66e42d
+        "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32,
66e42d
+        "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10", 16 );
66e42d
+      if (errtxt)
66e42d
+        goto failed;
66e42d
+    }
66e42d
+
66e42d
+  return 0; /* Succeeded. */
66e42d
+
66e42d
+ failed:
66e42d
+  if (report)
66e42d
+    report ("cmac", GCRY_MAC_CMAC_AES, what, errtxt);
66e42d
+  return GPG_ERR_SELFTEST_FAILED;
66e42d
+}
66e42d
+
66e42d
+
66e42d
+/* Run a full self-test for ALGO and return 0 on success.  */
66e42d
+static gpg_err_code_t
66e42d
+run_cmac_selftests (int algo, int extended, selftest_report_func_t report)
66e42d
+{
66e42d
+  gpg_err_code_t ec;
66e42d
+
66e42d
+  switch (algo)
66e42d
+    {
66e42d
+    case GCRY_MAC_CMAC_3DES:
66e42d
+      ec = selftests_cmac_tdes (extended, report);
66e42d
+      break;
66e42d
+    case GCRY_MAC_CMAC_AES:
66e42d
+      ec = selftests_cmac_aes (extended, report);
66e42d
+      break;
66e42d
+
66e42d
+    default:
66e42d
+      ec = GPG_ERR_MAC_ALGO;
66e42d
+      break;
66e42d
+    }
66e42d
+  return ec;
66e42d
+}
66e42d
+
66e42d
+
66e42d
+
66e42d
+
66e42d
+/* Run the selftests for CMAC with CMAC algorithm ALGO with optional
66e42d
+   reporting function REPORT.  */
66e42d
+gpg_error_t
66e42d
+_gcry_cmac_selftest (int algo, int extended, selftest_report_func_t report)
66e42d
+{
66e42d
+  gcry_err_code_t ec = 0;
66e42d
+
66e42d
+  if (!_gcry_mac_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, NULL ))
66e42d
+    {
66e42d
+      ec = run_cmac_selftests (algo, extended, report);
66e42d
+    }
66e42d
+  else
66e42d
+    {
66e42d
+      ec = GPG_ERR_MAC_ALGO;
66e42d
+      if (report)
66e42d
+        report ("mac", algo, "module", "algorithm not available");
66e42d
+    }
66e42d
+  return gpg_error (ec);
66e42d
+}
66e42d
diff -up libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest libgcrypt-1.8.3/src/cipher-proto.h
66e42d
--- libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest	2017-11-23 19:16:58.000000000 +0100
66e42d
+++ libgcrypt-1.8.3/src/cipher-proto.h	2019-05-31 17:29:34.574588234 +0200
66e42d
@@ -256,6 +256,8 @@ gcry_error_t _gcry_pk_selftest (int algo
66e42d
                                 selftest_report_func_t report);
66e42d
 gcry_error_t _gcry_hmac_selftest (int algo, int extended,
66e42d
                                   selftest_report_func_t report);
66e42d
+gcry_error_t _gcry_cmac_selftest (int algo, int extended,
66e42d
+                                  selftest_report_func_t report);
66e42d
 
66e42d
 gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
66e42d
 
66e42d
diff -up libgcrypt-1.8.3/src/fips.c.cmac-selftest libgcrypt-1.8.3/src/fips.c
66e42d
--- libgcrypt-1.8.3/src/fips.c.cmac-selftest	2018-11-01 15:40:36.051865535 +0100
66e42d
+++ libgcrypt-1.8.3/src/fips.c	2019-05-31 17:31:20.157756640 +0200
66e42d
@@ -521,29 +521,32 @@ run_digest_selftests (int extended)
66e42d
 
66e42d
 /* Run self-tests for all HMAC algorithms.  Return 0 on success. */
66e42d
 static int
66e42d
-run_hmac_selftests (int extended)
66e42d
+run_mac_selftests (int extended)
66e42d
 {
66e42d
-  static int algos[] =
66e42d
+  static int algos[][2] =
66e42d
     {
66e42d
-      GCRY_MD_SHA1,
66e42d
-      GCRY_MD_SHA224,
66e42d
-      GCRY_MD_SHA256,
66e42d
-      GCRY_MD_SHA384,
66e42d
-      GCRY_MD_SHA512,
66e42d
-      GCRY_MD_SHA3_224,
66e42d
-      GCRY_MD_SHA3_256,
66e42d
-      GCRY_MD_SHA3_384,
66e42d
-      GCRY_MD_SHA3_512,
66e42d
-      0
66e42d
+      { GCRY_MD_SHA1, 0 },
66e42d
+      { GCRY_MD_SHA224, 0 },
66e42d
+      { GCRY_MD_SHA256, 0 },
66e42d
+      { GCRY_MD_SHA384, 0 },
66e42d
+      { GCRY_MD_SHA512, 0 },
66e42d
+      { GCRY_MD_SHA3_224, 0 },
66e42d
+      { GCRY_MD_SHA3_256, 0 },
66e42d
+      { GCRY_MD_SHA3_384, 0 },
66e42d
+      { GCRY_MD_SHA3_512, 0 },
66e42d
+      { GCRY_MAC_CMAC_3DES, 1 },
66e42d
+      { GCRY_MAC_CMAC_AES, 1 },
66e42d
+      { 0, 0 }
66e42d
     };
66e42d
   int idx;
66e42d
   gpg_error_t err;
66e42d
   int anyerr = 0;
66e42d
 
66e42d
-  for (idx=0; algos[idx]; idx++)
66e42d
+  for (idx=0; algos[idx][0]; idx++)
66e42d
     {
66e42d
-      err = _gcry_hmac_selftest (algos[idx], extended, reporter);
66e42d
-      reporter ("hmac", algos[idx], NULL,
66e42d
+      err = algos[idx][1] ? _gcry_cmac_selftest (algos[idx][0], extended, reporter) :
66e42d
+        _gcry_hmac_selftest (algos[idx][0], extended, reporter);
66e42d
+      reporter (algos[idx][1] ? "cmac" : "hmac", algos[idx][0], NULL,
66e42d
                 err? gpg_strerror (err):NULL);
66e42d
       if (err)
66e42d
         anyerr = 1;
66e42d
@@ -747,7 +750,7 @@ _gcry_fips_run_selftests (int extended)
66e42d
   if (run_digest_selftests (extended))
66e42d
     goto leave;
66e42d
 
66e42d
-  if (run_hmac_selftests (extended))
66e42d
+  if (run_mac_selftests (extended))
66e42d
     goto leave;
66e42d
 
66e42d
   /* Run random tests before the pubkey tests because the latter