[821] | 1 | /* vi: set sw=4 ts=4: */
|
---|
| 2 | /*
|
---|
[2725] | 3 | * Utility routines.
|
---|
[821] | 4 | *
|
---|
| 5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
|
---|
| 6 | *
|
---|
[2725] | 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
---|
[821] | 8 | */
|
---|
| 9 |
|
---|
| 10 | #include "libbb.h"
|
---|
| 11 |
|
---|
[3621] | 12 | /* static const uint8_t ascii64[] ALIGN1 =
|
---|
[2725] | 13 | * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
---|
| 14 | */
|
---|
| 15 |
|
---|
| 16 | static int i64c(int i)
|
---|
[821] | 17 | {
|
---|
[2725] | 18 | i &= 0x3f;
|
---|
| 19 | if (i == 0)
|
---|
| 20 | return '.';
|
---|
| 21 | if (i == 1)
|
---|
| 22 | return '/';
|
---|
| 23 | if (i < 12)
|
---|
| 24 | return ('0' - 2 + i);
|
---|
| 25 | if (i < 38)
|
---|
| 26 | return ('A' - 12 + i);
|
---|
| 27 | return ('a' - 38 + i);
|
---|
| 28 | }
|
---|
[821] | 29 |
|
---|
[3232] | 30 | int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */)
|
---|
[2725] | 31 | {
|
---|
[3232] | 32 | /* was: x += ... */
|
---|
| 33 | int x = getpid() + monotonic_us();
|
---|
[2725] | 34 | do {
|
---|
| 35 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame
|
---|
| 36 | * (low-order bit is not "random", etc...),
|
---|
| 37 | * but for our purposes it is good enough */
|
---|
| 38 | x = x*1664525 + 1013904223;
|
---|
| 39 | /* BTW, Park and Miller's "minimal standard generator" is
|
---|
| 40 | * x = x*16807 % ((2^31)-1)
|
---|
| 41 | * It has no problem with visibly alternating lowest bit
|
---|
| 42 | * but is also weak in cryptographic sense + needs div,
|
---|
| 43 | * which needs more code (and slower) on many CPUs */
|
---|
| 44 | *p++ = i64c(x >> 16);
|
---|
| 45 | *p++ = i64c(x >> 22);
|
---|
| 46 | } while (--cnt);
|
---|
| 47 | *p = '\0';
|
---|
| 48 | return x;
|
---|
| 49 | }
|
---|
| 50 |
|
---|
[3232] | 51 | char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo)
|
---|
| 52 | {
|
---|
| 53 | int len = 2/2;
|
---|
| 54 | char *salt_ptr = salt;
|
---|
[3621] | 55 |
|
---|
| 56 | /* Standard chpasswd uses uppercase algos ("MD5", not "md5").
|
---|
| 57 | * Need to be case-insensitive in the code below.
|
---|
| 58 | */
|
---|
| 59 | if ((algo[0]|0x20) != 'd') { /* not des */
|
---|
[3232] | 60 | len = 8/2; /* so far assuming md5 */
|
---|
| 61 | *salt_ptr++ = '$';
|
---|
| 62 | *salt_ptr++ = '1';
|
---|
| 63 | *salt_ptr++ = '$';
|
---|
| 64 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA
|
---|
[3621] | 65 | if ((algo[0]|0x20) == 's') { /* sha */
|
---|
| 66 | salt[1] = '5' + (strcasecmp(algo, "sha512") == 0);
|
---|
[3232] | 67 | len = 16/2;
|
---|
| 68 | }
|
---|
| 69 | #endif
|
---|
| 70 | }
|
---|
| 71 | crypt_make_salt(salt_ptr, len);
|
---|
| 72 | return salt_ptr;
|
---|
| 73 | }
|
---|
| 74 |
|
---|
[2725] | 75 | #if ENABLE_USE_BB_CRYPT
|
---|
| 76 |
|
---|
| 77 | static char*
|
---|
| 78 | to64(char *s, unsigned v, int n)
|
---|
| 79 | {
|
---|
| 80 | while (--n >= 0) {
|
---|
| 81 | /* *s++ = ascii64[v & 0x3f]; */
|
---|
| 82 | *s++ = i64c(v);
|
---|
| 83 | v >>= 6;
|
---|
[821] | 84 | }
|
---|
[2725] | 85 | return s;
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | /*
|
---|
| 89 | * DES and MD5 crypt implementations are taken from uclibc.
|
---|
| 90 | * They were modified to not use static buffers.
|
---|
| 91 | */
|
---|
| 92 |
|
---|
| 93 | #include "pw_encrypt_des.c"
|
---|
| 94 | #include "pw_encrypt_md5.c"
|
---|
| 95 | #if ENABLE_USE_BB_CRYPT_SHA
|
---|
| 96 | #include "pw_encrypt_sha.c"
|
---|
[821] | 97 | #endif
|
---|
[1765] | 98 |
|
---|
[2725] | 99 | /* Other advanced crypt ids (TODO?): */
|
---|
| 100 | /* $2$ or $2a$: Blowfish */
|
---|
| 101 |
|
---|
| 102 | static struct const_des_ctx *des_cctx;
|
---|
| 103 | static struct des_ctx *des_ctx;
|
---|
| 104 |
|
---|
| 105 | /* my_crypt returns malloc'ed data */
|
---|
| 106 | static char *my_crypt(const char *key, const char *salt)
|
---|
| 107 | {
|
---|
| 108 | /* MD5 or SHA? */
|
---|
| 109 | if (salt[0] == '$' && salt[1] && salt[2] == '$') {
|
---|
| 110 | if (salt[1] == '1')
|
---|
| 111 | return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
|
---|
| 112 | #if ENABLE_USE_BB_CRYPT_SHA
|
---|
| 113 | if (salt[1] == '5' || salt[1] == '6')
|
---|
| 114 | return sha_crypt((char*)key, (char*)salt);
|
---|
| 115 | #endif
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | if (!des_cctx)
|
---|
| 119 | des_cctx = const_des_init();
|
---|
| 120 | des_ctx = des_init(des_ctx, des_cctx);
|
---|
| 121 | return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
|
---|
[821] | 122 | }
|
---|
[2725] | 123 |
|
---|
| 124 | /* So far nobody wants to have it public */
|
---|
| 125 | static void my_crypt_cleanup(void)
|
---|
| 126 | {
|
---|
| 127 | free(des_cctx);
|
---|
| 128 | free(des_ctx);
|
---|
| 129 | des_cctx = NULL;
|
---|
| 130 | des_ctx = NULL;
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
|
---|
| 134 | {
|
---|
| 135 | char *encrypted;
|
---|
| 136 |
|
---|
| 137 | encrypted = my_crypt(clear, salt);
|
---|
| 138 |
|
---|
| 139 | if (cleanup)
|
---|
| 140 | my_crypt_cleanup();
|
---|
| 141 |
|
---|
| 142 | return encrypted;
|
---|
| 143 | }
|
---|
| 144 |
|
---|
| 145 | #else /* if !ENABLE_USE_BB_CRYPT */
|
---|
| 146 |
|
---|
| 147 | char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
|
---|
| 148 | {
|
---|
[3621] | 149 | char *s;
|
---|
| 150 |
|
---|
| 151 | s = crypt(clear, salt);
|
---|
| 152 | /*
|
---|
| 153 | * glibc used to return "" on malformed salts (for example, ""),
|
---|
| 154 | * but since 2.17 it returns NULL.
|
---|
| 155 | */
|
---|
| 156 | return xstrdup(s ? s : "");
|
---|
[2725] | 157 | }
|
---|
| 158 |
|
---|
| 159 | #endif
|
---|