source: rtems-libbsd/freebsd/crypto/openssl/apps/passwd.c @ 0fecf49

5
Last change on this file since 0fecf49 was 0fecf49, checked in by Christian Mauderer <christian.mauderer@…>, on 03/26/19 at 09:19:22

bin/openssl: Import from FreeBSD.

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