(root)/
libxcrypt-4.4.36/
test/
crypt-gost-yescrypt.c
       1  /* Copyright (C) 2018 vt@altlinux.org
       2   * Copyright (C) 2018 Björn Esser besser82@fedoraproject.org
       3   *
       4   * Redistribution and use in source and binary forms, with or without
       5   * modification, are permitted.
       6   *
       7   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
       8   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       9   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      10   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      11   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      12   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      13   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      14   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      15   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      16   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      17   * SUCH DAMAGE.
      18   */
      19  
      20  #include "crypt-port.h"
      21  
      22  #if INCLUDE_gost_yescrypt
      23  
      24  #include "alg-gost3411-2012-hmac.h"
      25  
      26  #include <stdio.h>
      27  
      28  /* redefine outer hmac to this function to test entropy bypass */
      29  static void
      30  test_outer_hmac (const uint8_t *k, size_t n, const uint8_t *t, size_t len,
      31                   uint8_t *out32, gost_hmac_256_t *gostbuf);
      32  #define outer_gost_hmac256 test_outer_hmac
      33  #include "../lib/crypt-gost-yescrypt.c"
      34  
      35  static int test_mode = 0;
      36  
      37  static void
      38  test_outer_hmac (const uint8_t *k, size_t n, const uint8_t *t, size_t len,
      39                   uint8_t *out32, gost_hmac_256_t *gostbuf)
      40  {
      41    const uint8_t zero[32] = {0};
      42  
      43    /* Zero one of arguments to outer hmac. */
      44    if (test_mode & 1)
      45      {
      46        k = zero;
      47        n = sizeof (zero);
      48      }
      49    if (test_mode & 2)
      50      {
      51        t = zero;
      52        len = sizeof (zero);
      53      }
      54    gost_hmac256 (k, n, t, len, out32, gostbuf);
      55  }
      56  
      57  static int
      58  test_crypt_raw (int m, int p, int s, char **a, size_t *a_size)
      59  {
      60    char output[CRYPT_OUTPUT_SIZE];
      61    char pass[CRYPT_MAX_PASSPHRASE_SIZE];
      62    char pref[CRYPT_GENSALT_OUTPUT_SIZE];
      63    char scratch[ALG_SPECIFIC_SIZE];
      64    char *salt;
      65  
      66    test_mode = m;
      67    fprintf (stderr, ".");
      68    snprintf (pass, sizeof (pass), "%d", p);
      69    snprintf (pref, sizeof (pref), "%15d", s);
      70    salt = crypt_gensalt ("$gy$", 0, pref, (int) strlen(pref) + 1);
      71    if (!salt || salt[0] == '*')
      72      {
      73        fprintf(stderr, "ERROR: entropy test (gensalt) [%s]\n", pref);
      74        return 1;
      75      }
      76    crypt_gost_yescrypt_rn (pass, strlen (pass), salt, strlen (salt),
      77                            (uint8_t *) output, sizeof (output),
      78                            scratch, sizeof (scratch));
      79    if (output[0] == '*')
      80      {
      81        fprintf(stderr, "ERROR: entropy test (crypt)\n");
      82        return 1;
      83      }
      84    char *h = strrchr (output, '$') + 1;
      85    if (*a && strstr (*a, h))
      86      {
      87        fprintf (stderr, "ERROR: duplicated hash %s\n", output);
      88        return 1;
      89      }
      90    size_t len = strlen(h);
      91    *a = realloc (*a, *a_size + len + 1);
      92    strcpy (*a + *a_size, h);
      93    *a_size += len;
      94    (*a)[*a_size] = '\0';
      95  
      96    return 0;
      97  }
      98  
      99  int
     100  main (void)
     101  {
     102    int result = 0;
     103  
     104    /* Entropy tests
     105     * Replace left then right argument of outer hmac() with constant
     106     * and do hashing, verifying that output hashes are still different
     107     * when password or salt are changing.
     108     * Thus, we prove that entropy is still passing to the output not
     109     * depending on yescrypt. */
     110  
     111    int m, pp, ss;
     112    int etest = 0;
     113    char **a = malloc (sizeof (char*));
     114    size_t *a_size = malloc (sizeof (size_t));
     115  
     116    *a = malloc (sizeof (char));
     117    (*a)[0] = '\0';
     118    *a_size = 0;
     119  
     120    for (m = 1; m < 3; m++)
     121      {
     122        for (pp = 0; pp < 22; pp++)
     123          etest |= test_crypt_raw (m, pp, 0, a, a_size);
     124        for (ss = 0; ss < 22; ss++)
     125          etest |= test_crypt_raw (m, pp, ss, a, a_size);
     126      }
     127    fprintf (stderr, "\n");
     128    if (etest)
     129      fprintf (stderr, "ERROR: entropy test failed.\n");
     130    else
     131      fprintf (stderr, "   ok: entropy test\n");
     132    result |= etest;
     133  
     134    free (*a);
     135    free (a);
     136    free (a_size);
     137  
     138    return result;
     139  }
     140  
     141  #else
     142  
     143  int
     144  main (void)
     145  {
     146    return 77; /* UNSUPPORTED */
     147  }
     148  
     149  #endif /* INCLUDE_gost_yescrypt */