Home | History | Annotate | Line # | Download | only in apps
      1 /*
      2  * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include <string.h>
     11 
     12 #include "apps.h"
     13 #include "progs.h"
     14 
     15 #include <openssl/bio.h>
     16 #include <openssl/err.h>
     17 #include <openssl/evp.h>
     18 #include <openssl/rand.h>
     19 #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0)
     20 #include <openssl/des.h>
     21 #endif
     22 #include <openssl/md5.h>
     23 #include <openssl/sha.h>
     24 
     25 static const unsigned char cov_2char[64] = {
     26     /* from crypto/des/fcrypt.c */
     27     0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
     28     0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
     29     0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
     30     0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
     31     0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
     32     0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
     33     0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
     34     0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
     35 };
     36 
     37 static const char ascii_dollar[] = { 0x24, 0x00 };
     38 
     39 typedef enum {
     40     passwd_unset = 0,
     41     passwd_md5,
     42     passwd_apr1,
     43     passwd_sha256,
     44     passwd_sha512,
     45     passwd_aixmd5
     46 } passwd_modes;
     47 
     48 static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
     49     char *passwd, BIO *out, int quiet, int table,
     50     int reverse, size_t pw_maxlen, passwd_modes mode);
     51 
     52 typedef enum OPTION_choice {
     53     OPT_COMMON,
     54     OPT_IN,
     55     OPT_NOVERIFY,
     56     OPT_QUIET,
     57     OPT_TABLE,
     58     OPT_REVERSE,
     59     OPT_APR1,
     60     OPT_1,
     61     OPT_5,
     62     OPT_6,
     63     OPT_AIXMD5,
     64     OPT_SALT,
     65     OPT_STDIN,
     66     OPT_R_ENUM,
     67     OPT_PROV_ENUM
     68 } OPTION_CHOICE;
     69 
     70 const OPTIONS passwd_options[] = {
     71     { OPT_HELP_STR, 1, '-', "Usage: %s [options] [password]\n" },
     72 
     73     OPT_SECTION("General"),
     74     { "help", OPT_HELP, '-', "Display this summary" },
     75 
     76     OPT_SECTION("Input"),
     77     { "in", OPT_IN, '<', "Read passwords from file" },
     78     { "noverify", OPT_NOVERIFY, '-',
     79         "Never verify when reading password from terminal" },
     80     { "stdin", OPT_STDIN, '-', "Read passwords from stdin" },
     81 
     82     OPT_SECTION("Output"),
     83     { "quiet", OPT_QUIET, '-', "No warnings" },
     84     { "table", OPT_TABLE, '-', "Format output as table" },
     85     { "reverse", OPT_REVERSE, '-', "Switch table columns" },
     86 
     87     OPT_SECTION("Cryptographic"),
     88     { "salt", OPT_SALT, 's', "Use provided salt" },
     89     { "6", OPT_6, '-', "SHA512-based password algorithm" },
     90     { "5", OPT_5, '-', "SHA256-based password algorithm" },
     91     { "apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant" },
     92     { "1", OPT_1, '-', "MD5-based password algorithm" },
     93     { "aixmd5", OPT_AIXMD5, '-', "AIX MD5-based password algorithm" },
     94 
     95     OPT_R_OPTIONS,
     96     OPT_PROV_OPTIONS,
     97 
     98     OPT_PARAMETERS(),
     99     { "password", 0, 0, "Password text to digest (optional)" },
    100     { NULL }
    101 };
    102 
    103 int passwd_main(int argc, char **argv)
    104 {
    105     BIO *in = NULL;
    106     char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL;
    107     char *salt_malloc = NULL, *passwd_malloc = NULL, *prog;
    108     OPTION_CHOICE o;
    109     int in_stdin = 0, pw_source_defined = 0;
    110 #ifndef OPENSSL_NO_UI_CONSOLE
    111     int in_noverify = 0;
    112 #endif
    113     int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
    114     int ret = 1;
    115     passwd_modes mode = passwd_unset;
    116     size_t passwd_malloc_size = 0;
    117     size_t pw_maxlen = 256; /* arbitrary limit, should be enough for most
    118                              * passwords */
    119 
    120     prog = opt_init(argc, argv, passwd_options);
    121     while ((o = opt_next()) != OPT_EOF) {
    122         switch (o) {
    123         case OPT_EOF:
    124         case OPT_ERR:
    125         opthelp:
    126             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
    127             goto end;
    128         case OPT_HELP:
    129             opt_help(passwd_options);
    130             ret = 0;
    131             goto end;
    132         case OPT_IN:
    133             if (pw_source_defined)
    134                 goto opthelp;
    135             infile = opt_arg();
    136             pw_source_defined = 1;
    137             break;
    138         case OPT_NOVERIFY:
    139 #ifndef OPENSSL_NO_UI_CONSOLE
    140             in_noverify = 1;
    141 #endif
    142             break;
    143         case OPT_QUIET:
    144             quiet = 1;
    145             break;
    146         case OPT_TABLE:
    147             table = 1;
    148             break;
    149         case OPT_REVERSE:
    150             reverse = 1;
    151             break;
    152         case OPT_1:
    153             if (mode != passwd_unset)
    154                 goto opthelp;
    155             mode = passwd_md5;
    156             break;
    157         case OPT_5:
    158             if (mode != passwd_unset)
    159                 goto opthelp;
    160             mode = passwd_sha256;
    161             break;
    162         case OPT_6:
    163             if (mode != passwd_unset)
    164                 goto opthelp;
    165             mode = passwd_sha512;
    166             break;
    167         case OPT_APR1:
    168             if (mode != passwd_unset)
    169                 goto opthelp;
    170             mode = passwd_apr1;
    171             break;
    172         case OPT_AIXMD5:
    173             if (mode != passwd_unset)
    174                 goto opthelp;
    175             mode = passwd_aixmd5;
    176             break;
    177         case OPT_SALT:
    178             passed_salt = 1;
    179             salt = opt_arg();
    180             break;
    181         case OPT_STDIN:
    182             if (pw_source_defined)
    183                 goto opthelp;
    184             in_stdin = 1;
    185             pw_source_defined = 1;
    186             break;
    187         case OPT_R_CASES:
    188             if (!opt_rand(o))
    189                 goto end;
    190             break;
    191         case OPT_PROV_CASES:
    192             if (!opt_provider(o))
    193                 goto end;
    194             break;
    195         }
    196     }
    197 
    198     /* All remaining arguments are the password text */
    199     argc = opt_num_rest();
    200     argv = opt_rest();
    201     if (*argv != NULL) {
    202         if (pw_source_defined)
    203             goto opthelp;
    204         pw_source_defined = 1;
    205         passwds = argv;
    206     }
    207 
    208     if (!app_RAND_load())
    209         goto end;
    210 
    211     if (mode == passwd_unset) {
    212         /* use default */
    213         mode = passwd_md5;
    214     }
    215 
    216     if (infile != NULL && in_stdin) {
    217         BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog);
    218         goto end;
    219     }
    220 
    221     if (infile != NULL || in_stdin) {
    222         /*
    223          * If in_stdin is true, we know that infile is NULL, and that
    224          * bio_open_default() will give us back an alias for stdin.
    225          */
    226         in = bio_open_default(infile, 'r', FORMAT_TEXT);
    227         if (in == NULL)
    228             goto end;
    229     }
    230 
    231     if (passwds == NULL) {
    232         /* no passwords on the command line */
    233 
    234         passwd_malloc_size = pw_maxlen + 2;
    235         /* longer than necessary so that we can warn about truncation */
    236         passwd = passwd_malloc = app_malloc(passwd_malloc_size, "password buffer");
    237     }
    238 
    239     if ((in == NULL) && (passwds == NULL)) {
    240         /*
    241          * we use the following method to make sure what
    242          * in the 'else' section is always compiled, to
    243          * avoid rot of not-frequently-used code.
    244          */
    245         if (1) {
    246 #ifndef OPENSSL_NO_UI_CONSOLE
    247             /* build a null-terminated list */
    248             static char *passwds_static[2] = { NULL, NULL };
    249 
    250             passwds = passwds_static;
    251             if (in == NULL) {
    252                 if (EVP_read_pw_string(passwd_malloc, passwd_malloc_size, "Password: ",
    253                         !(passed_salt || in_noverify))
    254                     != 0)
    255                     goto end;
    256             }
    257             passwds[0] = passwd_malloc;
    258         } else {
    259 #endif
    260             BIO_printf(bio_err, "password required\n");
    261             goto end;
    262         }
    263     }
    264 
    265     if (in == NULL) {
    266         assert(passwds != NULL);
    267         assert(*passwds != NULL);
    268 
    269         do { /* loop over list of passwords */
    270             passwd = *passwds++;
    271             if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out,
    272                     quiet, table, reverse, pw_maxlen, mode))
    273                 goto end;
    274         } while (*passwds != NULL);
    275     } else {
    276         /* in != NULL */
    277         int done;
    278 
    279         assert(passwd != NULL);
    280         do {
    281             int r = BIO_gets(in, passwd, pw_maxlen + 1);
    282             if (r > 0) {
    283                 char *c = (strchr(passwd, '\n'));
    284                 if (c != NULL) {
    285                     *c = 0; /* truncate at newline */
    286                 } else {
    287                     /* ignore rest of line */
    288                     char trash[BUFSIZ];
    289                     do
    290                         r = BIO_gets(in, trash, sizeof(trash));
    291                     while ((r > 0) && (!strchr(trash, '\n')));
    292                 }
    293 
    294                 if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet,
    295                         table, reverse, pw_maxlen, mode))
    296                     goto end;
    297             }
    298             done = (r <= 0);
    299         } while (!done);
    300     }
    301     ret = 0;
    302 
    303 end:
    304 #if 0
    305     ERR_print_errors(bio_err);
    306 #endif
    307     OPENSSL_free(salt_malloc);
    308     OPENSSL_free(passwd_malloc);
    309     BIO_free(in);
    310     return ret;
    311 }
    312 
    313 /*
    314  * MD5-based password algorithm (should probably be available as a library
    315  * function; then the static buffer would not be acceptable). For magic
    316  * string "1", this should be compatible to the MD5-based BSD password
    317  * algorithm. For 'magic' string "apr1", this is compatible to the MD5-based
    318  * Apache password algorithm. (Apparently, the Apache password algorithm is
    319  * identical except that the 'magic' string was changed -- the laziest
    320  * application of the NIH principle I've ever encountered.)
    321  */
    322 static char *md5crypt(const char *passwd, const char *magic, const char *salt)
    323 {
    324     /* "$apr1$..salt..$.......md5hash..........\0" */
    325     static char out_buf[6 + 9 + 24 + 2];
    326     unsigned char buf[MD5_DIGEST_LENGTH];
    327     char ascii_magic[5]; /* "apr1" plus '\0' */
    328     char ascii_salt[9]; /* Max 8 chars plus '\0' */
    329     char *ascii_passwd = NULL;
    330     char *salt_out;
    331     int n;
    332     unsigned int i;
    333     EVP_MD_CTX *md = NULL, *md2 = NULL;
    334     size_t passwd_len, salt_len, magic_len;
    335 
    336     passwd_len = strlen(passwd);
    337 
    338     out_buf[0] = 0;
    339     magic_len = strlen(magic);
    340     OPENSSL_strlcpy(ascii_magic, magic, sizeof(ascii_magic));
    341 #ifdef CHARSET_EBCDIC
    342     if ((magic[0] & 0x80) != 0) /* High bit is 1 in EBCDIC alnums */
    343         ebcdic2ascii(ascii_magic, ascii_magic, magic_len);
    344 #endif
    345 
    346     /* The salt gets truncated to 8 chars */
    347     OPENSSL_strlcpy(ascii_salt, salt, sizeof(ascii_salt));
    348     salt_len = strlen(ascii_salt);
    349 #ifdef CHARSET_EBCDIC
    350     ebcdic2ascii(ascii_salt, ascii_salt, salt_len);
    351 #endif
    352 
    353 #ifdef CHARSET_EBCDIC
    354     ascii_passwd = OPENSSL_strdup(passwd);
    355     if (ascii_passwd == NULL)
    356         return NULL;
    357     ebcdic2ascii(ascii_passwd, ascii_passwd, passwd_len);
    358     passwd = ascii_passwd;
    359 #endif
    360 
    361     if (magic_len > 0) {
    362         OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
    363 
    364         if (magic_len > 4) /* assert it's  "1" or "apr1" */
    365             goto err;
    366 
    367         OPENSSL_strlcat(out_buf, ascii_magic, sizeof(out_buf));
    368         OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
    369     }
    370 
    371     OPENSSL_strlcat(out_buf, ascii_salt, sizeof(out_buf));
    372 
    373     if (strlen(out_buf) > 6 + 8) /* assert "$apr1$..salt.." */
    374         goto err;
    375 
    376     salt_out = out_buf;
    377     if (magic_len > 0)
    378         salt_out += 2 + magic_len;
    379 
    380     assert(salt_len <= 8);
    381 
    382     md = EVP_MD_CTX_new();
    383     if (md == NULL
    384         || !EVP_DigestInit_ex(md, EVP_md5(), NULL)
    385         || !EVP_DigestUpdate(md, passwd, passwd_len))
    386         goto err;
    387 
    388     if (magic_len > 0)
    389         if (!EVP_DigestUpdate(md, ascii_dollar, 1)
    390             || !EVP_DigestUpdate(md, ascii_magic, magic_len)
    391             || !EVP_DigestUpdate(md, ascii_dollar, 1))
    392             goto err;
    393 
    394     if (!EVP_DigestUpdate(md, ascii_salt, salt_len))
    395         goto err;
    396 
    397     md2 = EVP_MD_CTX_new();
    398     if (md2 == NULL
    399         || !EVP_DigestInit_ex(md2, EVP_md5(), NULL)
    400         || !EVP_DigestUpdate(md2, passwd, passwd_len)
    401         || !EVP_DigestUpdate(md2, ascii_salt, salt_len)
    402         || !EVP_DigestUpdate(md2, passwd, passwd_len)
    403         || !EVP_DigestFinal_ex(md2, buf, NULL))
    404         goto err;
    405 
    406     for (i = passwd_len; i > sizeof(buf); i -= sizeof(buf)) {
    407         if (!EVP_DigestUpdate(md, buf, sizeof(buf)))
    408             goto err;
    409     }
    410     if (!EVP_DigestUpdate(md, buf, i))
    411         goto err;
    412 
    413     n = passwd_len;
    414     while (n) {
    415         if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1))
    416             goto err;
    417         n >>= 1;
    418     }
    419     if (!EVP_DigestFinal_ex(md, buf, NULL))
    420         goto err;
    421 
    422     for (i = 0; i < 1000; i++) {
    423         if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
    424             goto err;
    425         if (!EVP_DigestUpdate(md2,
    426                 (i & 1) ? (const unsigned char *)passwd : buf,
    427                 (i & 1) ? passwd_len : sizeof(buf)))
    428             goto err;
    429         if (i % 3) {
    430             if (!EVP_DigestUpdate(md2, ascii_salt, salt_len))
    431                 goto err;
    432         }
    433         if (i % 7) {
    434             if (!EVP_DigestUpdate(md2, passwd, passwd_len))
    435                 goto err;
    436         }
    437         if (!EVP_DigestUpdate(md2,
    438                 (i & 1) ? buf : (const unsigned char *)passwd,
    439                 (i & 1) ? sizeof(buf) : passwd_len))
    440             goto err;
    441         if (!EVP_DigestFinal_ex(md2, buf, NULL))
    442             goto err;
    443     }
    444     EVP_MD_CTX_free(md2);
    445     EVP_MD_CTX_free(md);
    446     md2 = NULL;
    447     md = NULL;
    448 
    449     {
    450         /* transform buf into output string */
    451         unsigned char buf_perm[sizeof(buf)];
    452         int dest, source;
    453         char *output;
    454 
    455         /* silly output permutation */
    456         for (dest = 0, source = 0; dest < 14;
    457             dest++, source = (source + 6) % 17)
    458             buf_perm[dest] = buf[source];
    459         buf_perm[14] = buf[5];
    460         buf_perm[15] = buf[11];
    461 #ifndef PEDANTIC /* Unfortunately, this generates a "no \
    462                   * effect" warning */
    463         assert(16 == sizeof(buf_perm));
    464 #endif
    465 
    466         output = salt_out + salt_len;
    467         assert(output == out_buf + strlen(out_buf));
    468 
    469         *output++ = ascii_dollar[0];
    470 
    471         for (i = 0; i < 15; i += 3) {
    472             *output++ = cov_2char[buf_perm[i + 2] & 0x3f];
    473             *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) | (buf_perm[i + 2] >> 6)];
    474             *output++ = cov_2char[((buf_perm[i] & 3) << 4) | (buf_perm[i + 1] >> 4)];
    475             *output++ = cov_2char[buf_perm[i] >> 2];
    476         }
    477         assert(i == 15);
    478         *output++ = cov_2char[buf_perm[i] & 0x3f];
    479         *output++ = cov_2char[buf_perm[i] >> 6];
    480         *output = 0;
    481         assert(strlen(out_buf) < sizeof(out_buf));
    482 #ifdef CHARSET_EBCDIC
    483         ascii2ebcdic(out_buf, out_buf, strlen(out_buf));
    484 #endif
    485     }
    486 
    487     return out_buf;
    488 
    489 err:
    490     OPENSSL_free(ascii_passwd);
    491     EVP_MD_CTX_free(md2);
    492     EVP_MD_CTX_free(md);
    493     return NULL;
    494 }
    495 
    496 /*
    497  * SHA based password algorithm, describe by Ulrich Drepper here:
    498  * https://www.akkadia.org/drepper/SHA-crypt.txt
    499  * (note that it's in the public domain)
    500  */
    501 static char *shacrypt(const char *passwd, const char *magic, const char *salt)
    502 {
    503     /* Prefix for optional rounds specification.  */
    504     static const char rounds_prefix[] = "rounds=";
    505     /* Maximum salt string length.  */
    506 #define SALT_LEN_MAX 16
    507     /* Default number of rounds if not explicitly specified.  */
    508 #define ROUNDS_DEFAULT 5000
    509     /* Minimum number of rounds.  */
    510 #define ROUNDS_MIN 1000
    511     /* Maximum number of rounds.  */
    512 #define ROUNDS_MAX 999999999
    513 
    514     /* "$6$rounds=<N>$......salt......$...shahash(up to 86 chars)...\0" */
    515     static char out_buf[3 + 17 + 17 + 86 + 1];
    516     unsigned char buf[SHA512_DIGEST_LENGTH];
    517     unsigned char temp_buf[SHA512_DIGEST_LENGTH];
    518     size_t buf_size = 0;
    519     char ascii_magic[2];
    520     char ascii_salt[17]; /* Max 16 chars plus '\0' */
    521     char *ascii_passwd = NULL;
    522     size_t n;
    523     EVP_MD_CTX *md = NULL, *md2 = NULL;
    524     const EVP_MD *sha = NULL;
    525     size_t passwd_len, salt_len, magic_len;
    526     unsigned int rounds = ROUNDS_DEFAULT; /* Default */
    527     char rounds_custom = 0;
    528     char *p_bytes = NULL;
    529     char *s_bytes = NULL;
    530     char *cp = NULL;
    531 
    532     passwd_len = strlen(passwd);
    533     magic_len = strlen(magic);
    534 
    535     /* assert it's "5" or "6" */
    536     if (magic_len != 1)
    537         return NULL;
    538 
    539     switch (magic[0]) {
    540     case '5':
    541         sha = EVP_sha256();
    542         buf_size = 32;
    543         break;
    544     case '6':
    545         sha = EVP_sha512();
    546         buf_size = 64;
    547         break;
    548     default:
    549         return NULL;
    550     }
    551 
    552     if (strncmp(salt, rounds_prefix, sizeof(rounds_prefix) - 1) == 0) {
    553         const char *num = salt + sizeof(rounds_prefix) - 1;
    554         char *endp;
    555         unsigned long int srounds = strtoul(num, &endp, 10);
    556         if (*endp == '$') {
    557             salt = endp + 1;
    558             if (srounds > ROUNDS_MAX)
    559                 rounds = ROUNDS_MAX;
    560             else if (srounds < ROUNDS_MIN)
    561                 rounds = ROUNDS_MIN;
    562             else
    563                 rounds = (unsigned int)srounds;
    564             rounds_custom = 1;
    565         } else {
    566             return NULL;
    567         }
    568     }
    569 
    570     OPENSSL_strlcpy(ascii_magic, magic, sizeof(ascii_magic));
    571 #ifdef CHARSET_EBCDIC
    572     if ((magic[0] & 0x80) != 0) /* High bit is 1 in EBCDIC alnums */
    573         ebcdic2ascii(ascii_magic, ascii_magic, magic_len);
    574 #endif
    575 
    576     /* The salt gets truncated to 16 chars */
    577     OPENSSL_strlcpy(ascii_salt, salt, sizeof(ascii_salt));
    578     salt_len = strlen(ascii_salt);
    579 #ifdef CHARSET_EBCDIC
    580     ebcdic2ascii(ascii_salt, ascii_salt, salt_len);
    581 #endif
    582 
    583 #ifdef CHARSET_EBCDIC
    584     ascii_passwd = OPENSSL_strdup(passwd);
    585     if (ascii_passwd == NULL)
    586         return NULL;
    587     ebcdic2ascii(ascii_passwd, ascii_passwd, passwd_len);
    588     passwd = ascii_passwd;
    589 #endif
    590 
    591     out_buf[0] = 0;
    592     OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
    593     OPENSSL_strlcat(out_buf, ascii_magic, sizeof(out_buf));
    594     OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
    595     if (rounds_custom) {
    596         char tmp_buf[80]; /* "rounds=999999999" */
    597 
    598         BIO_snprintf(tmp_buf, sizeof(tmp_buf), "rounds=%u", rounds);
    599 #ifdef CHARSET_EBCDIC
    600         /* In case we're really on a ASCII based platform and just pretend */
    601         if (tmp_buf[0] != 0x72) /* ASCII 'r' */
    602             ebcdic2ascii(tmp_buf, tmp_buf, strlen(tmp_buf));
    603 #endif
    604         OPENSSL_strlcat(out_buf, tmp_buf, sizeof(out_buf));
    605         OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
    606     }
    607     OPENSSL_strlcat(out_buf, ascii_salt, sizeof(out_buf));
    608 
    609     /* assert "$5$rounds=999999999$......salt......" */
    610     if (strlen(out_buf) > 3 + 17 * rounds_custom + salt_len)
    611         goto err;
    612 
    613     md = EVP_MD_CTX_new();
    614     if (md == NULL
    615         || !EVP_DigestInit_ex(md, sha, NULL)
    616         || !EVP_DigestUpdate(md, passwd, passwd_len)
    617         || !EVP_DigestUpdate(md, ascii_salt, salt_len))
    618         goto err;
    619 
    620     md2 = EVP_MD_CTX_new();
    621     if (md2 == NULL
    622         || !EVP_DigestInit_ex(md2, sha, NULL)
    623         || !EVP_DigestUpdate(md2, passwd, passwd_len)
    624         || !EVP_DigestUpdate(md2, ascii_salt, salt_len)
    625         || !EVP_DigestUpdate(md2, passwd, passwd_len)
    626         || !EVP_DigestFinal_ex(md2, buf, NULL))
    627         goto err;
    628 
    629     for (n = passwd_len; n > buf_size; n -= buf_size) {
    630         if (!EVP_DigestUpdate(md, buf, buf_size))
    631             goto err;
    632     }
    633     if (!EVP_DigestUpdate(md, buf, n))
    634         goto err;
    635 
    636     n = passwd_len;
    637     while (n) {
    638         if (!EVP_DigestUpdate(md,
    639                 (n & 1) ? buf : (const unsigned char *)passwd,
    640                 (n & 1) ? buf_size : passwd_len))
    641             goto err;
    642         n >>= 1;
    643     }
    644     if (!EVP_DigestFinal_ex(md, buf, NULL))
    645         goto err;
    646 
    647     /* P sequence */
    648     if (!EVP_DigestInit_ex(md2, sha, NULL))
    649         goto err;
    650 
    651     for (n = passwd_len; n > 0; n--)
    652         if (!EVP_DigestUpdate(md2, passwd, passwd_len))
    653             goto err;
    654 
    655     if (!EVP_DigestFinal_ex(md2, temp_buf, NULL))
    656         goto err;
    657 
    658     if ((p_bytes = OPENSSL_zalloc(passwd_len)) == NULL)
    659         goto err;
    660     for (cp = p_bytes, n = passwd_len; n > buf_size; n -= buf_size, cp += buf_size)
    661         memcpy(cp, temp_buf, buf_size);
    662     memcpy(cp, temp_buf, n);
    663 
    664     /* S sequence */
    665     if (!EVP_DigestInit_ex(md2, sha, NULL))
    666         goto err;
    667 
    668     for (n = 16 + buf[0]; n > 0; n--)
    669         if (!EVP_DigestUpdate(md2, ascii_salt, salt_len))
    670             goto err;
    671 
    672     if (!EVP_DigestFinal_ex(md2, temp_buf, NULL))
    673         goto err;
    674 
    675     if ((s_bytes = OPENSSL_zalloc(salt_len)) == NULL)
    676         goto err;
    677     for (cp = s_bytes, n = salt_len; n > buf_size; n -= buf_size, cp += buf_size)
    678         memcpy(cp, temp_buf, buf_size);
    679     memcpy(cp, temp_buf, n);
    680 
    681     for (n = 0; n < rounds; n++) {
    682         if (!EVP_DigestInit_ex(md2, sha, NULL))
    683             goto err;
    684         if (!EVP_DigestUpdate(md2,
    685                 (n & 1) ? (const unsigned char *)p_bytes : buf,
    686                 (n & 1) ? passwd_len : buf_size))
    687             goto err;
    688         if (n % 3) {
    689             if (!EVP_DigestUpdate(md2, s_bytes, salt_len))
    690                 goto err;
    691         }
    692         if (n % 7) {
    693             if (!EVP_DigestUpdate(md2, p_bytes, passwd_len))
    694                 goto err;
    695         }
    696         if (!EVP_DigestUpdate(md2,
    697                 (n & 1) ? buf : (const unsigned char *)p_bytes,
    698                 (n & 1) ? buf_size : passwd_len))
    699             goto err;
    700         if (!EVP_DigestFinal_ex(md2, buf, NULL))
    701             goto err;
    702     }
    703     EVP_MD_CTX_free(md2);
    704     EVP_MD_CTX_free(md);
    705     md2 = NULL;
    706     md = NULL;
    707     OPENSSL_free(p_bytes);
    708     OPENSSL_free(s_bytes);
    709     p_bytes = NULL;
    710     s_bytes = NULL;
    711 
    712     cp = out_buf + strlen(out_buf);
    713     *cp++ = ascii_dollar[0];
    714 
    715 #define b64_from_24bit(B2, B1, B0, N)                       \
    716     do {                                                    \
    717         unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
    718         int i = (N);                                        \
    719         while (i-- > 0) {                                   \
    720             *cp++ = cov_2char[w & 0x3f];                    \
    721             w >>= 6;                                        \
    722         }                                                   \
    723     } while (0)
    724 
    725     switch (magic[0]) {
    726     case '5':
    727         b64_from_24bit(buf[0], buf[10], buf[20], 4);
    728         b64_from_24bit(buf[21], buf[1], buf[11], 4);
    729         b64_from_24bit(buf[12], buf[22], buf[2], 4);
    730         b64_from_24bit(buf[3], buf[13], buf[23], 4);
    731         b64_from_24bit(buf[24], buf[4], buf[14], 4);
    732         b64_from_24bit(buf[15], buf[25], buf[5], 4);
    733         b64_from_24bit(buf[6], buf[16], buf[26], 4);
    734         b64_from_24bit(buf[27], buf[7], buf[17], 4);
    735         b64_from_24bit(buf[18], buf[28], buf[8], 4);
    736         b64_from_24bit(buf[9], buf[19], buf[29], 4);
    737         b64_from_24bit(0, buf[31], buf[30], 3);
    738         break;
    739     case '6':
    740         b64_from_24bit(buf[0], buf[21], buf[42], 4);
    741         b64_from_24bit(buf[22], buf[43], buf[1], 4);
    742         b64_from_24bit(buf[44], buf[2], buf[23], 4);
    743         b64_from_24bit(buf[3], buf[24], buf[45], 4);
    744         b64_from_24bit(buf[25], buf[46], buf[4], 4);
    745         b64_from_24bit(buf[47], buf[5], buf[26], 4);
    746         b64_from_24bit(buf[6], buf[27], buf[48], 4);
    747         b64_from_24bit(buf[28], buf[49], buf[7], 4);
    748         b64_from_24bit(buf[50], buf[8], buf[29], 4);
    749         b64_from_24bit(buf[9], buf[30], buf[51], 4);
    750         b64_from_24bit(buf[31], buf[52], buf[10], 4);
    751         b64_from_24bit(buf[53], buf[11], buf[32], 4);
    752         b64_from_24bit(buf[12], buf[33], buf[54], 4);
    753         b64_from_24bit(buf[34], buf[55], buf[13], 4);
    754         b64_from_24bit(buf[56], buf[14], buf[35], 4);
    755         b64_from_24bit(buf[15], buf[36], buf[57], 4);
    756         b64_from_24bit(buf[37], buf[58], buf[16], 4);
    757         b64_from_24bit(buf[59], buf[17], buf[38], 4);
    758         b64_from_24bit(buf[18], buf[39], buf[60], 4);
    759         b64_from_24bit(buf[40], buf[61], buf[19], 4);
    760         b64_from_24bit(buf[62], buf[20], buf[41], 4);
    761         b64_from_24bit(0, 0, buf[63], 2);
    762         break;
    763     default:
    764         goto err;
    765     }
    766     *cp = '\0';
    767 #ifdef CHARSET_EBCDIC
    768     ascii2ebcdic(out_buf, out_buf, strlen(out_buf));
    769 #endif
    770 
    771     return out_buf;
    772 
    773 err:
    774     EVP_MD_CTX_free(md2);
    775     EVP_MD_CTX_free(md);
    776     OPENSSL_free(p_bytes);
    777     OPENSSL_free(s_bytes);
    778     OPENSSL_free(ascii_passwd);
    779     return NULL;
    780 }
    781 
    782 static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
    783     char *passwd, BIO *out, int quiet, int table,
    784     int reverse, size_t pw_maxlen, passwd_modes mode)
    785 {
    786     char *hash = NULL;
    787 
    788     assert(salt_p != NULL);
    789     assert(salt_malloc_p != NULL);
    790 
    791     /* first make sure we have a salt */
    792     if (!passed_salt) {
    793         size_t saltlen = 0;
    794         size_t i;
    795 
    796         if (mode == passwd_md5 || mode == passwd_apr1 || mode == passwd_aixmd5)
    797             saltlen = 8;
    798 
    799         if (mode == passwd_sha256 || mode == passwd_sha512)
    800             saltlen = 16;
    801 
    802         assert(saltlen != 0);
    803 
    804         if (*salt_malloc_p == NULL)
    805             *salt_p = *salt_malloc_p = app_malloc(saltlen + 1, "salt buffer");
    806         if (RAND_bytes((unsigned char *)*salt_p, saltlen) <= 0)
    807             goto end;
    808 
    809         for (i = 0; i < saltlen; i++)
    810             (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
    811         (*salt_p)[i] = 0;
    812 #ifdef CHARSET_EBCDIC
    813         /* The password encryption function will convert back to ASCII */
    814         ascii2ebcdic(*salt_p, *salt_p, saltlen);
    815 #endif
    816     }
    817 
    818     assert(*salt_p != NULL);
    819 
    820     /* truncate password if necessary */
    821     if ((strlen(passwd) > pw_maxlen)) {
    822         if (!quiet)
    823             /*
    824              * XXX: really we should know how to print a size_t, not cast it
    825              */
    826             BIO_printf(bio_err,
    827                 "Warning: truncating password to %u characters\n",
    828                 (unsigned)pw_maxlen);
    829         passwd[pw_maxlen] = 0;
    830     }
    831     assert(strlen(passwd) <= pw_maxlen);
    832 
    833     /* now compute password hash */
    834     if (mode == passwd_md5 || mode == passwd_apr1)
    835         hash = md5crypt(passwd, (mode == passwd_md5 ? "1" : "apr1"), *salt_p);
    836     if (mode == passwd_aixmd5)
    837         hash = md5crypt(passwd, "", *salt_p);
    838     if (mode == passwd_sha256 || mode == passwd_sha512)
    839         hash = shacrypt(passwd, (mode == passwd_sha256 ? "5" : "6"), *salt_p);
    840     assert(hash != NULL);
    841 
    842     if (table && !reverse)
    843         BIO_printf(out, "%s\t%s\n", passwd, hash);
    844     else if (table && reverse)
    845         BIO_printf(out, "%s\t%s\n", hash, passwd);
    846     else
    847         BIO_printf(out, "%s\n", hash);
    848     return 1;
    849 
    850 end:
    851     return 0;
    852 }
    853