(root)/
libxcrypt-4.4.36/
test/
gensalt.c
       1  #include "crypt-port.h"
       2  
       3  #include <errno.h>
       4  #include <stdio.h>
       5  #include <stdlib.h>
       6  
       7  static const char *const entropy[] =
       8  {
       9    "\x58\x35\xcd\x26\x03\xab\x2c\x14\x92\x13\x1e\x59\xb0\xbc\xfe\xd5",
      10    "\x9b\x35\xa2\x45\xeb\x68\x9e\x8f\xd9\xa9\x09\x71\xcc\x4d\x21\x44",
      11    "\x25\x13\xc5\x94\xc3\x93\x1d\xf4\xfd\xd4\x4f\xbd\x10\xe5\x28\x08",
      12    "\xa0\x2d\x35\x70\xa8\x0b\xc3\xad\xdf\x61\x69\xb3\x19\xda\x7e\x8d",
      13    0
      14  };
      15  
      16  #if INCLUDE_descrypt
      17  static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"};
      18  #endif
      19  #if INCLUDE_bigcrypt && !INCLUDE_descrypt
      20  static const char *const big_expected_output[] =
      21  {
      22    "Mp............",
      23    "Pp............",
      24    "ZH............",
      25    "Uh............"
      26  };
      27  #endif
      28  #if INCLUDE_bsdicrypt
      29  static const char *const bsdi_expected_output[] =
      30  {
      31    "_J9..MJHn",
      32    "_J9..PKXc",
      33    "_J9..ZAFl",
      34    "_J9..UqGB"
      35  };
      36  static const char *const bsdi_expected_output_r[] =
      37  {
      38    "_/.2.MJHn",
      39    "_/.2.PKXc",
      40    "_/.2.ZAFl",
      41    "_/.2.UqGB"
      42  };
      43  static const char *const bsdi_expected_output_l[] =
      44  {
      45    "_/...MJHn",
      46    "_/...PKXc",
      47    "_/...ZAFl",
      48    "_/...UqGB"
      49  };
      50  static const char *const bsdi_expected_output_h[] =
      51  {
      52    "_zzzzMJHn",
      53    "_zzzzPKXc",
      54    "_zzzzZAFl",
      55    "_zzzzUqGB"
      56  };
      57  #endif
      58  #if INCLUDE_md5crypt
      59  static const char *const md5_expected_output[] =
      60  {
      61    "$1$MJHnaAke",
      62    "$1$PKXc3hCO",
      63    "$1$ZAFlICwY",
      64    "$1$UqGBkVu0"
      65  };
      66  #endif
      67  #if INCLUDE_sunmd5
      68  static const char *const sunmd5_expected_output[] =
      69  {
      70    "$md5,rounds=55349$BPm.fm03$",
      71    "$md5,rounds=72501$WKoucttX$",
      72    "$md5,rounds=42259$3HtkHq/x$",
      73    "$md5,rounds=73773$p.5e9AQf$",
      74  };
      75  static const char *const sunmd5_expected_output_l[] =
      76  {
      77    "$md5,rounds=55349$BPm.fm03$",
      78    "$md5,rounds=72501$WKoucttX$",
      79    "$md5,rounds=42259$3HtkHq/x$",
      80    "$md5,rounds=73773$p.5e9AQf$",
      81  };
      82  static const char *const sunmd5_expected_output_h[] =
      83  {
      84    "$md5,rounds=4294924340$BPm.fm03$",
      85    "$md5,rounds=4294941492$WKoucttX$",
      86    "$md5,rounds=4294911250$3HtkHq/x$",
      87    "$md5,rounds=4294942764$p.5e9AQf$",
      88  };
      89  #endif
      90  #if INCLUDE_sha1crypt
      91  static const char *const sha1_expected_output[] =
      92  {
      93    "$sha1$248488$ggu.H673kaZ5$",
      94    "$sha1$248421$SWqudaxXA5L0$",
      95    "$sha1$257243$RAtkIrDxEovH$",
      96    "$sha1$250464$1j.eVxRfNAPO$",
      97  };
      98  static const char *const sha1_expected_output_l[] =
      99  {
     100    "$sha1$4$ggu.H673kaZ5$",
     101    "$sha1$4$SWqudaxXA5L0$",
     102    "$sha1$4$RAtkIrDxEovH$",
     103    "$sha1$4$1j.eVxRfNAPO$",
     104  };
     105  static const char *const sha1_expected_output_h[] =
     106  {
     107    "$sha1$3643984551$ggu.H673kaZ5$",
     108    "$sha1$4200450659$SWqudaxXA5L0$",
     109    "$sha1$3946507480$RAtkIrDxEovH$",
     110    "$sha1$3486175838$1j.eVxRfNAPO$",
     111  };
     112  #endif
     113  #if INCLUDE_sha256crypt
     114  static const char *const sha256_expected_output[] =
     115  {
     116    "$5$MJHnaAkegEVYHsFK",
     117    "$5$PKXc3hCOSyMqdaEQ",
     118    "$5$ZAFlICwYRETzIzIj",
     119    "$5$UqGBkVu01rurVZqg"
     120  };
     121  static const char *const sha256_expected_output_r[] =
     122  {
     123    "$5$rounds=10191$MJHnaAkegEVYHsFK",
     124    "$5$rounds=10191$PKXc3hCOSyMqdaEQ",
     125    "$5$rounds=10191$ZAFlICwYRETzIzIj",
     126    "$5$rounds=10191$UqGBkVu01rurVZqg"
     127  };
     128  static const char *const sha256_expected_output_l[] =
     129  {
     130    "$5$rounds=1000$MJHnaAkegEVYHsFK",
     131    "$5$rounds=1000$PKXc3hCOSyMqdaEQ",
     132    "$5$rounds=1000$ZAFlICwYRETzIzIj",
     133    "$5$rounds=1000$UqGBkVu01rurVZqg"
     134  };
     135  static const char *const sha256_expected_output_h[] =
     136  {
     137    "$5$rounds=999999999$MJHnaAkegEVYHsFK",
     138    "$5$rounds=999999999$PKXc3hCOSyMqdaEQ",
     139    "$5$rounds=999999999$ZAFlICwYRETzIzIj",
     140    "$5$rounds=999999999$UqGBkVu01rurVZqg"
     141  };
     142  #endif
     143  #if INCLUDE_sha512crypt
     144  static const char *const sha512_expected_output[] =
     145  {
     146    "$6$MJHnaAkegEVYHsFK",
     147    "$6$PKXc3hCOSyMqdaEQ",
     148    "$6$ZAFlICwYRETzIzIj",
     149    "$6$UqGBkVu01rurVZqg"
     150  };
     151  static const char *const sha512_expected_output_r[] =
     152  {
     153    "$6$rounds=10191$MJHnaAkegEVYHsFK",
     154    "$6$rounds=10191$PKXc3hCOSyMqdaEQ",
     155    "$6$rounds=10191$ZAFlICwYRETzIzIj",
     156    "$6$rounds=10191$UqGBkVu01rurVZqg"
     157  };
     158  static const char *const sha512_expected_output_l[] =
     159  {
     160    "$6$rounds=1000$MJHnaAkegEVYHsFK",
     161    "$6$rounds=1000$PKXc3hCOSyMqdaEQ",
     162    "$6$rounds=1000$ZAFlICwYRETzIzIj",
     163    "$6$rounds=1000$UqGBkVu01rurVZqg"
     164  };
     165  static const char *const sha512_expected_output_h[] =
     166  {
     167    "$6$rounds=999999999$MJHnaAkegEVYHsFK",
     168    "$6$rounds=999999999$PKXc3hCOSyMqdaEQ",
     169    "$6$rounds=999999999$ZAFlICwYRETzIzIj",
     170    "$6$rounds=999999999$UqGBkVu01rurVZqg"
     171  };
     172  #endif
     173  #if INCLUDE_bcrypt
     174  static const char *const bcrypt_b_expected_output[] =
     175  {
     176    "$2b$05$UBVLHeMpJ/QQCv3XqJx8zO",
     177    "$2b$05$kxUgPcrmlm9XoOjvxCyfP.",
     178    "$2b$05$HPNDjKMRFdR7zC87CMSmA.",
     179    "$2b$05$mAyzaIeJu41dWUkxEbn8hO"
     180  };
     181  static const char *const bcrypt_b_expected_output_l[] =
     182  {
     183    "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO",
     184    "$2b$04$kxUgPcrmlm9XoOjvxCyfP.",
     185    "$2b$04$HPNDjKMRFdR7zC87CMSmA.",
     186    "$2b$04$mAyzaIeJu41dWUkxEbn8hO"
     187  };
     188  static const char *const bcrypt_b_expected_output_h[] =
     189  {
     190    "$2b$31$UBVLHeMpJ/QQCv3XqJx8zO",
     191    "$2b$31$kxUgPcrmlm9XoOjvxCyfP.",
     192    "$2b$31$HPNDjKMRFdR7zC87CMSmA.",
     193    "$2b$31$mAyzaIeJu41dWUkxEbn8hO"
     194  };
     195  #endif
     196  #if INCLUDE_bcrypt_a
     197  static const char *const bcrypt_a_expected_output[] =
     198  {
     199    "$2a$05$UBVLHeMpJ/QQCv3XqJx8zO",
     200    "$2a$05$kxUgPcrmlm9XoOjvxCyfP.",
     201    "$2a$05$HPNDjKMRFdR7zC87CMSmA.",
     202    "$2a$05$mAyzaIeJu41dWUkxEbn8hO"
     203  };
     204  #endif
     205  #if INCLUDE_bcrypt_y
     206  static const char *const bcrypt_y_expected_output[] =
     207  {
     208    "$2y$05$UBVLHeMpJ/QQCv3XqJx8zO",
     209    "$2y$05$kxUgPcrmlm9XoOjvxCyfP.",
     210    "$2y$05$HPNDjKMRFdR7zC87CMSmA.",
     211    "$2y$05$mAyzaIeJu41dWUkxEbn8hO"
     212  };
     213  #endif
     214  #if INCLUDE_yescrypt
     215  static const char *yescrypt_expected_output[] =
     216  {
     217    "$y$j9T$MJHnaAkegEVYHsFKkmfzJ1",
     218    "$y$j9T$PKXc3hCOSyMqdaEQArI62/",
     219    "$y$j9T$ZAFlICwYRETzIzIjEIC86.",
     220    "$y$j9T$UqGBkVu01rurVZqgNchTB0"
     221  };
     222  static const char *yescrypt_expected_output_l[] =
     223  {
     224    "$y$j75$MJHnaAkegEVYHsFKkmfzJ1",
     225    "$y$j75$PKXc3hCOSyMqdaEQArI62/",
     226    "$y$j75$ZAFlICwYRETzIzIjEIC86.",
     227    "$y$j75$UqGBkVu01rurVZqgNchTB0"
     228  };
     229  static const char *yescrypt_expected_output_h[] =
     230  {
     231    "$y$jFT$MJHnaAkegEVYHsFKkmfzJ1",
     232    "$y$jFT$PKXc3hCOSyMqdaEQArI62/",
     233    "$y$jFT$ZAFlICwYRETzIzIjEIC86.",
     234    "$y$jFT$UqGBkVu01rurVZqgNchTB0"
     235  };
     236  #endif
     237  #if INCLUDE_scrypt
     238  static const char *scrypt_expected_output[] =
     239  {
     240    "$7$CU..../....MJHnaAkegEVYHsFKkmfzJ1",
     241    "$7$CU..../....PKXc3hCOSyMqdaEQArI62/",
     242    "$7$CU..../....ZAFlICwYRETzIzIjEIC86.",
     243    "$7$CU..../....UqGBkVu01rurVZqgNchTB0"
     244  };
     245  static const char *scrypt_expected_output_l[] =
     246  {
     247    "$7$BU..../....MJHnaAkegEVYHsFKkmfzJ1",
     248    "$7$BU..../....PKXc3hCOSyMqdaEQArI62/",
     249    "$7$BU..../....ZAFlICwYRETzIzIjEIC86.",
     250    "$7$BU..../....UqGBkVu01rurVZqgNchTB0"
     251  };
     252  static const char *scrypt_expected_output_h[] =
     253  {
     254    "$7$GU..../....MJHnaAkegEVYHsFKkmfzJ1",
     255    "$7$GU..../....PKXc3hCOSyMqdaEQArI62/",
     256    "$7$GU..../....ZAFlICwYRETzIzIjEIC86.",
     257    "$7$GU..../....UqGBkVu01rurVZqgNchTB0"
     258  };
     259  #endif
     260  #if INCLUDE_gost_yescrypt
     261  static const char *gost_yescrypt_expected_output[] =
     262  {
     263    "$gy$j9T$MJHnaAkegEVYHsFKkmfzJ1",
     264    "$gy$j9T$PKXc3hCOSyMqdaEQArI62/",
     265    "$gy$j9T$ZAFlICwYRETzIzIjEIC86.",
     266    "$gy$j9T$UqGBkVu01rurVZqgNchTB0"
     267  };
     268  static const char *gost_yescrypt_expected_output_l[] =
     269  {
     270    "$gy$j75$MJHnaAkegEVYHsFKkmfzJ1",
     271    "$gy$j75$PKXc3hCOSyMqdaEQArI62/",
     272    "$gy$j75$ZAFlICwYRETzIzIjEIC86.",
     273    "$gy$j75$UqGBkVu01rurVZqgNchTB0"
     274  };
     275  static const char *gost_yescrypt_expected_output_h[] =
     276  {
     277    "$gy$jFT$MJHnaAkegEVYHsFKkmfzJ1",
     278    "$gy$jFT$PKXc3hCOSyMqdaEQArI62/",
     279    "$gy$jFT$ZAFlICwYRETzIzIjEIC86.",
     280    "$gy$jFT$UqGBkVu01rurVZqgNchTB0"
     281  };
     282  #endif
     283  
     284  struct testcase
     285  {
     286    const char *prefix;
     287    const char *const *expected_output;
     288    unsigned int expected_len;
     289    unsigned int expected_auto_len;
     290    unsigned long rounds;
     291  };
     292  
     293  // For all hashing methods with a linear cost parameter (that is,
     294  // DES/BSD, MD5/Sun, SHA1, SHA256, and SHA512), crypt_gensalt will
     295  // accept any value in the range of 'unsigned long' and clip it to the
     296  // actual valid range.
     297  #define MIN_LINEAR_COST 1
     298  #define MAX_LINEAR_COST ULONG_MAX
     299  
     300  static const struct testcase testcases[] =
     301  {
     302  #if INCLUDE_descrypt
     303    { "",      des_expected_output,       2,  0, 0 },
     304    // DES doesn't have variable round count.
     305  #endif
     306  #if INCLUDE_bigcrypt && !INCLUDE_descrypt
     307    { "",      big_expected_output,       14,  0, 0 },
     308    // bigcrypt doesn't have variable round count.
     309  #endif
     310  #if INCLUDE_bsdicrypt
     311    { "_",     bsdi_expected_output,      9,  0, 0 },
     312    // BSDI/DES always emits a round count.
     313    // The _r expectation is used to verify that even inputs are
     314    // made odd, rather than rejected.
     315    { "_",     bsdi_expected_output_r,    9,  0, 16384 },
     316    { "_",     bsdi_expected_output_l,    9,  0, MIN_LINEAR_COST },
     317    { "_",     bsdi_expected_output_h,    9,  0, MAX_LINEAR_COST },
     318  #endif
     319  #if INCLUDE_md5crypt
     320    { "$1$",   md5_expected_output,      11,  0, 0 },
     321    // MD5/BSD doesn't have variable round count.
     322  #endif
     323  #if INCLUDE_sunmd5
     324    { "$md5",  sunmd5_expected_output,   27,  0, 0 },
     325    // MD5/Sun always emits a round count.
     326    { "$md5", sunmd5_expected_output_l,  27,  0, MIN_LINEAR_COST },
     327    { "$md5", sunmd5_expected_output_h,  32,  0, MAX_LINEAR_COST },
     328  #endif
     329  #if INCLUDE_sha1crypt
     330    { "$sha1", sha1_expected_output,     26, 34, 0 },
     331    // SHA1/PBKDF always emits a round count.
     332    { "$sha1", sha1_expected_output_l,   21, 29, MIN_LINEAR_COST },
     333    { "$sha1", sha1_expected_output_h,   30, 38, MAX_LINEAR_COST },
     334  #endif
     335  #if INCLUDE_sha256crypt
     336    { "$5$",   sha256_expected_output,   19,  0, 0 },
     337    { "$5$",   sha256_expected_output_r, 32,  0, 10191 },
     338    { "$5$",   sha256_expected_output_l, 31,  0, MIN_LINEAR_COST },
     339    { "$5$",   sha256_expected_output_h, 36,  0, MAX_LINEAR_COST },
     340  #endif
     341  #if INCLUDE_sha512crypt
     342    { "$6$",   sha512_expected_output,   19,  0, 0 },
     343    { "$6$",   sha512_expected_output_r, 32,  0, 10191 },
     344    { "$6$",   sha512_expected_output_l, 31,  0, MIN_LINEAR_COST },
     345    { "$6$",   sha512_expected_output_h, 36,  0, MAX_LINEAR_COST },
     346  #endif
     347  #if INCLUDE_bcrypt
     348    { "$2b$",  bcrypt_b_expected_output, 29,  0, 0 },
     349    // bcrypt always emits a cost parameter.
     350    // bcrypt's cost parameter is exponential, not linear, and
     351    // values outside the documented range are errors.
     352    { "$2b$",  bcrypt_b_expected_output_l, 29,  0, 4 },
     353    { "$2b$",  bcrypt_b_expected_output_h, 29,  0, 31 },
     354  #endif
     355    // Salt generation for legacy bcrypt variants uses the same code as
     356    // the 'b' variant, so we don't bother testing them on non-default
     357    // rounds.
     358  #if INCLUDE_bcrypt_a
     359    { "$2a$",  bcrypt_a_expected_output, 29,  0, 0 },
     360  #endif
     361  #if INCLUDE_bcrypt_y
     362    { "$2y$",  bcrypt_y_expected_output, 29,  0, 0 },
     363  #endif
     364  #if INCLUDE_yescrypt
     365    { "$y$",   yescrypt_expected_output,   29, 29,  0 },
     366    { "$y$",   yescrypt_expected_output_l, 29, 29,  1 },
     367    { "$y$",   yescrypt_expected_output_h, 29, 29, 11 },
     368  #endif
     369  #if INCLUDE_scrypt
     370    { "$7$",   scrypt_expected_output,   36, 36,  0 },
     371    { "$7$",   scrypt_expected_output_l, 36, 36,  6 },
     372    { "$7$",   scrypt_expected_output_h, 36, 36, 11 },
     373  #endif
     374  #if INCLUDE_gost_yescrypt
     375    { "$gy$",  gost_yescrypt_expected_output,   30, 30,  0 },
     376    { "$gy$",  gost_yescrypt_expected_output_l, 30, 30,  1 },
     377    { "$gy$",  gost_yescrypt_expected_output_h, 30, 30, 11 },
     378  #endif
     379    { 0, 0, 0, 0, 0 }
     380  };
     381  
     382  /* The "best available" hashing method.  */
     383  #if INCLUDE_yescrypt
     384  # define EXPECTED_DEFAULT_PREFIX "$y$"
     385  #elif INCLUDE_bcrypt
     386  # define EXPECTED_DEFAULT_PREFIX "$2b$"
     387  #elif INCLUDE_sha512crypt
     388  # define EXPECTED_DEFAULT_PREFIX "$6$"
     389  #endif
     390  
     391  #if CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX
     392  # ifndef EXPECTED_DEFAULT_PREFIX
     393  #  error "Which hashing algorithm is the default?"
     394  # endif
     395  #else
     396  # ifdef EXPECTED_DEFAULT_PREFIX
     397  #  error "Default hashing algorithm should be available"
     398  # endif
     399  #endif
     400  
     401  int
     402  main (void)
     403  {
     404    int status = 0;
     405    unsigned int ent;
     406    const struct testcase *tcase;
     407    char output[CRYPT_GENSALT_OUTPUT_SIZE];
     408    char prev_output[CRYPT_GENSALT_OUTPUT_SIZE];
     409  
     410    for (tcase = testcases; tcase->prefix; tcase++)
     411      {
     412        memset (prev_output, 0, CRYPT_GENSALT_OUTPUT_SIZE);
     413        for (ent = 0; ent < ARRAY_SIZE (entropy); ent++)
     414          {
     415            memset (output, 0, CRYPT_GENSALT_OUTPUT_SIZE);
     416            char *salt = crypt_gensalt_rn (tcase->prefix, tcase->rounds,
     417                                           entropy[ent], 16,
     418                                           output, CRYPT_GENSALT_OUTPUT_SIZE);
     419            if (salt == 0)
     420              {
     421                if (entropy[ent] == 0 && errno == ENOSYS)
     422                  {
     423                    fprintf (stderr,
     424                             "UNSUPPORTED: %s/%lu/auto-entropy -> ENOSYS\n",
     425                             tcase->prefix, tcase->rounds);
     426                  }
     427                else
     428                  {
     429                    fprintf (stderr, "ERROR: %s/%lu/%u -> 0\n",
     430                             tcase->prefix, tcase->rounds, ent);
     431                    status = 1;
     432                  }
     433                continue;
     434              }
     435            size_t slen = strlen (salt);
     436            unsigned int expected_len =
     437              (!entropy[ent] && tcase->expected_auto_len) ?
     438              tcase->expected_auto_len : tcase->expected_len;
     439            if (slen != expected_len)
     440              {
     441                fprintf (stderr,
     442                         "ERROR: %s/%lu/%u -> %s (expected len=%u got %zu)\n",
     443                         tcase->prefix, tcase->rounds, ent, salt,
     444                         expected_len, slen);
     445                status = 1;
     446              }
     447            else if (strncmp (salt, tcase->prefix, strlen (tcase->prefix)))
     448              {
     449                fprintf (stderr, "ERROR: %s/%lu/%u -> %s (prefix wrong)\n",
     450                         tcase->prefix, tcase->rounds, ent, salt);
     451                status = 1;
     452              }
     453            else if (!strcmp (salt, prev_output))
     454              {
     455                fprintf (stderr, "ERROR: %s/%lu/%u -> %s (same as prev)\n",
     456                         tcase->prefix, tcase->rounds, ent, salt);
     457                status = 1;
     458              }
     459            else if (entropy[ent] &&  strcmp (salt, tcase->expected_output[ent]))
     460              {
     461                fprintf (stderr, "ERROR: %s/%lu/%u -> %s (expected %s)\n",
     462                         tcase->prefix, tcase->rounds, ent, salt,
     463                         tcase->expected_output[ent]);
     464                status = 1;
     465              }
     466            else
     467              fprintf (stderr, "   ok: %s/%lu/%u -> %s\n",
     468                       tcase->prefix, tcase->rounds, ent, salt);
     469  
     470            strcpy_or_abort (prev_output, CRYPT_GENSALT_OUTPUT_SIZE, salt);
     471  
     472            /* Test if crypt works with this salt. */
     473            if (!tcase->rounds)
     474              {
     475  #define PASSW "alexander"
     476                static struct crypt_data a, b;
     477                if (!crypt_rn (PASSW, salt, &a, sizeof(a)))
     478                  {
     479                    fprintf (stderr, "ERROR: %s/%u -> crypt(gensalt) fail\n",
     480                             tcase->prefix, ent);
     481                    status = 1;
     482                  }
     483                else if (!crypt_rn (PASSW, a.output, &b, sizeof(b)))
     484                  {
     485                    fprintf (stderr, "ERROR: %s/%u -> crypt(crypt(gensalt)) fail\n",
     486                             tcase->prefix, ent);
     487                    status = 1;
     488                  }
     489                else if (strcmp (a.output, b.output))
     490                  {
     491                    fprintf (stderr, "ERROR: %s/%u -> crypt(gensalt) != crypt(crypt(gensalt))\n",
     492                             tcase->prefix, ent);
     493                    status = 1;
     494                  }
     495                else
     496                  {
     497                    fprintf (stderr, "   ok: %s/%u -> crypt works with this salt\n",
     498                             tcase->prefix, ent);
     499                  }
     500              }
     501          }
     502      }
     503  #if CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX
     504    /* Passing a null pointer as the prefix argument to crypt_gensalt is
     505       supposed to tell it to use the "best available" hashing method.  */
     506    {
     507      char *setting1, *setting2;
     508      setting1 = crypt_gensalt_ra (EXPECTED_DEFAULT_PREFIX, 0, entropy[0], 16);
     509      setting2 = crypt_gensalt_ra (0, 0, entropy[0], 16);
     510      if ((setting1 == 0 && setting2 != 0) ||
     511          (setting1 != 0 && setting2 == 0) ||
     512          (setting1 != 0 && setting2 != 0 && strcmp (setting1, setting2)))
     513        {
     514          printf ("FAILED: crypt_gensalt defaulting to $y$\n"
     515                  "  $y$ -> %s\n"
     516                  "  null -> %s\n",
     517                  setting1, setting2);
     518          status = 1;
     519        }
     520      free (setting1);
     521      free (setting2);
     522    }
     523  #else
     524    {
     525      char *setting = crypt_gensalt_ra (0, 0, entropy[0], 16);
     526      if (setting)
     527        {
     528          printf ("FAILED: crypt_gensalt null -> %s (null expected)\n", setting);
     529          status = 1;
     530        }
     531      free (setting);
     532    }
     533  #endif
     534    return status;
     535  }