1  /* Test HMAC_SHA256 and PBKDF2_HMAC_SHA256 implementations.
       2   *
       3   * Written by Zack Weinberg <zackw at panix.com> in 2018.
       4   * Incorporates standard test vectors from sources documented below.
       5   * To the extent possible under law, the named authors have waived all
       6   * copyright and related or neighboring rights to this work.
       7   *
       8   * See https://creativecommons.org/publicdomain/zero/1.0/ for further
       9   * details.
      10   */
      11  
      12  #include "crypt-port.h"
      13  #include "alg-sha256.h"
      14  
      15  #include <stdio.h>
      16  
      17  #if INCLUDE_scrypt || INCLUDE_yescrypt || INCLUDE_gost_yescrypt
      18  
      19  struct hmac_sha256_test
      20  {
      21    const char *key;
      22    const char *message;
      23    uint8_t digest[32];
      24  };
      25  
      26  /* HMAC-SHA256 test vectors from RFC 4231.  */
      27  static const struct hmac_sha256_test hmac_sha256_tests[] =
      28  {
      29    {
      30      "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
      31      "\x0b\x0b\x0b\x0b",
      32      "Hi There",
      33      "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b"
      34      "\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7"
      35    },
      36    {
      37      "Jefe",
      38      "what do ya want for nothing?",
      39      "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7"
      40      "\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43"
      41    },
      42    {
      43      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      44      "\xaa\xaa\xaa\xaa",
      45      "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
      46      "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
      47      "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
      48      "\xdd\xdd",
      49      "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7"
      50      "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe"
      51    },
      52    {
      53      "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
      54      "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
      55      "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
      56      "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
      57      "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
      58      "\xcd\xcd",
      59      "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a"
      60      "\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b"
      61    },
      62    {
      63      "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
      64      "\x0c\x0c\x0c\x0c",
      65      "Test With Truncation",
      66      /* N.B. the RFC only supplies the high 16 bytes of this vector; the rest
      67         were filled in with the current implementation's output.  */
      68      "\xa3\xb6\x16\x74\x73\x10\x0e\xe0\x6e\x0c\x79\x6c\x29\x55\x55\x2b"
      69      "\xfa\x6f\x7c\x0a\x6a\x8a\xef\x8b\x93\xf8\x60\xaa\xb0\xcd\x20\xc5"
      70    },
      71    {
      72      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      73      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      74      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      75      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      76      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      77      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      78      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      79      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      80      "\xaa\xaa\xaa",
      81      "Test Using Larger Than Block-Size Key - Hash Key First",
      82      "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f"
      83      "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54"
      84    },
      85    {
      86      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      87      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      88      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      89      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      90      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      91      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      92      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      93      "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
      94      "\xaa\xaa\xaa",
      95      "This is a test using a larger than block-size key and a larger t"
      96      "han block-size data. The key needs to be hashed before being use"
      97      "d by the HMAC algorithm.",
      98      "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44"
      99      "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2"
     100    }
     101  };
     102  
     103  struct pbkdf2_hmac_sha256_test
     104  {
     105    const char *passwd;
     106    const char *salt;
     107    uint32_t plen;
     108    uint32_t slen;
     109    uint32_t c;
     110    uint32_t dklen;
     111    const char *dk; /* [dklen] */
     112  };
     113  
     114  struct pbkdf2_hmac_sha256_test pbkdf2_hmac_sha256_tests[] =
     115  {
     116    /* PBKDF2-HMAC-SHA256 test vectors from RFC 7914.  */
     117    {
     118      "passwd", "salt", 6, 4, 1, 64,
     119      "\x55\xac\x04\x6e\x56\xe3\x08\x9f\xec\x16\x91\xc2\x25\x44\xb6\x05"
     120      "\xf9\x41\x85\x21\x6d\xde\x04\x65\xe6\x8b\x9d\x57\xc2\x0d\xac\xbc"
     121      "\x49\xca\x9c\xcc\xf1\x79\xb6\x45\x99\x16\x64\xb3\x9d\x77\xef\x31"
     122      "\x7c\x71\xb8\x45\xb1\xe3\x0b\xd5\x09\x11\x20\x41\xd3\xa1\x97\x83"
     123    },
     124    {
     125      "Password", "NaCl", 8, 4, 80000, 64,
     126      "\x4d\xdc\xd8\xf6\x0b\x98\xbe\x21\x83\x0c\xee\x5e\xf2\x27\x01\xf9"
     127      "\x64\x1a\x44\x18\xd0\x4c\x04\x14\xae\xff\x08\x87\x6b\x34\xab\x56"
     128      "\xa1\xd4\x25\xa1\x22\x58\x33\x54\x9a\xdb\x84\x1b\x51\xc9\xb3\x17"
     129      "\x6a\x27\x2b\xde\xbb\xa1\xd0\x78\x47\x8f\x62\xb3\x97\xf3\x3c\x8d"
     130    },
     131    /* Test vectors from RFC 6070 (which defines PBKDF2-HMAC-SHA1)
     132       recalculated with SHA256 instead of SHA1 and a larger dklen by
     133       'aaz' at <https://stackoverflow.com/a/5136918/388520>.  */
     134    {
     135      "password", "salt", 8, 4, 1, 32,
     136      "\x12\x0f\xb6\xcf\xfc\xf8\xb3\x2c\x43\xe7\x22\x52\x56\xc4\xf8\x37"
     137      "\xa8\x65\x48\xc9\x2c\xcc\x35\x48\x08\x05\x98\x7c\xb7\x0b\xe1\x7b"
     138    },
     139    {
     140      "password", "salt", 8, 4, 2, 32,
     141      "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0"
     142      "\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43"
     143    },
     144    {
     145      "password", "salt", 8, 4, 4096, 32,
     146      "\xc5\xe4\x78\xd5\x92\x88\xc8\x41\xaa\x53\x0d\xb6\x84\x5c\x4c\x8d"
     147      "\x96\x28\x93\xa0\x01\xce\x4e\x11\xa4\x96\x38\x73\xaa\x98\x13\x4a"
     148    },
     149  #ifdef SLOW_TESTS
     150    /* With this test vector included, the program takes 40 seconds to run
     151       to completion on a 2017-generation x86.  Without, half a second.  */
     152    {
     153      "password", "salt", 8, 4, 16777216, 32,
     154      "\xcf\x81\xc6\x6f\xe8\xcf\xc0\x4d\x1f\x31\xec\xb6\x5d\xab\x40\x89"
     155      "\xf7\xf1\x79\xe8\x9b\x3b\x0b\xcb\x17\xad\x10\xe3\xac\x6e\xba\x46"
     156    },
     157  #endif
     158    {
     159      "passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt",
     160      24, 36, 4096, 40,
     161      "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf"
     162      "\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1"
     163      "\xc6\x35\x51\x8c\x7d\xac\x47\xe9"
     164    },
     165    {
     166      "pass\0word", "sa\0lt", 9, 5, 4096, 16,
     167      "\x89\xb6\x9d\x05\x16\xf8\x29\x89\x3c\x69\x62\x26\x65\x0a\x86\x87"
     168    }
     169  };
     170  
     171  
     172  static void
     173  report_failure(const char *tag, size_t n, size_t len,
     174                 const uint8_t expected[], const uint8_t actual[])
     175  {
     176    size_t i;
     177    printf ("FAIL: %s/%zu:\n  exp:", tag, n);
     178    for (i = 0; i < len; i++)
     179      {
     180        if (i % 4 == 0)
     181          putchar (' ');
     182        printf ("%02x", (unsigned int)(unsigned char)expected[i]);
     183      }
     184    printf ("\n  got:");
     185    for (i = 0; i < len; i++)
     186      {
     187        if (i % 4 == 0)
     188          putchar (' ');
     189        printf ("%02x", (unsigned int)(unsigned char)actual[i]);
     190      }
     191    putchar ('\n');
     192    putchar ('\n');
     193  }
     194  
     195  static int
     196  test_hmac_sha256 (void)
     197  {
     198    uint8_t output[32];
     199    HMAC_SHA256_CTX ctx;
     200    int status = 0;
     201    size_t j;
     202    for (size_t i = 0; i < ARRAY_SIZE (hmac_sha256_tests); i++)
     203      {
     204        const struct hmac_sha256_test *t = &hmac_sha256_tests[i];
     205        HMAC_SHA256_Buf (t->key, strlen (t->key),
     206                         t->message, strlen (t->message),
     207                         output);
     208        if (memcmp (output, t->digest, 32))
     209          {
     210            report_failure ("HMAC-SHA256 (one shot)",
     211                            i, 32, t->digest, output);
     212            status = 1;
     213          }
     214        HMAC_SHA256_Init(&ctx, t->key, strlen (t->key));
     215        for (j = 0; t->message[j] != '\0'; j++)
     216          HMAC_SHA256_Update(&ctx, &t->message[j], 1);
     217        HMAC_SHA256_Final(output, &ctx);
     218        if (memcmp (output, t->digest, 32))
     219          {
     220            report_failure ("HMAC-SHA256 (incremental)",
     221                            i, 32, t->digest, output);
     222            status = 1;
     223          }
     224      }
     225    return status;
     226  }
     227  
     228  static int
     229  test_pbkdf2_hmac_sha256 (void)
     230  {
     231    uint8_t output[64];
     232    int status = 0;
     233    for (size_t i = 0; i < ARRAY_SIZE (pbkdf2_hmac_sha256_tests); i++)
     234      {
     235        const struct pbkdf2_hmac_sha256_test *t = &pbkdf2_hmac_sha256_tests[i];
     236        assert (t->dklen <= sizeof output);
     237  
     238        PBKDF2_SHA256 ((const unsigned char *)t->passwd, t->plen,
     239                       (const unsigned char *)t->salt, t->slen,
     240                       t->c, output, t->dklen);
     241        if (memcmp (output, t->dk, t->dklen))
     242          {
     243            report_failure ("PBKDF2-HMAC-SHA256", i, t->dklen,
     244                            (const unsigned char *)t->dk, output);
     245            status = 1;
     246          }
     247      }
     248    return status;
     249  }
     250  
     251  
     252  int
     253  main (void)
     254  {
     255    int status = 0;
     256    status |= test_hmac_sha256 ();
     257    status |= test_pbkdf2_hmac_sha256 ();
     258    return status;
     259  }
     260  
     261  #else /* INCLUDE_scrypt || INCLUDE_yescrypt */
     262  
     263  int
     264  main (void)
     265  {
     266    return 77; /* UNSUPPORTED */
     267  }
     268  
     269  #endif