diff options
Diffstat (limited to 'libbb/pw_encrypt.c')
-rw-r--r-- | libbb/pw_encrypt.c | 113 |
1 files changed, 58 insertions, 55 deletions
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 3463fd95b..93653de9f 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c | |||
@@ -13,48 +13,11 @@ | |||
13 | #endif | 13 | #endif |
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | 15 | ||
16 | /* static const uint8_t ascii64[] ALIGN1 = | 16 | #include "pw_ascii64.c" |
17 | * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
18 | */ | ||
19 | |||
20 | static int i64c(int i) | ||
21 | { | ||
22 | i &= 0x3f; | ||
23 | if (i == 0) | ||
24 | return '.'; | ||
25 | if (i == 1) | ||
26 | return '/'; | ||
27 | if (i < 12) | ||
28 | return ('0' - 2 + i); | ||
29 | if (i < 38) | ||
30 | return ('A' - 12 + i); | ||
31 | return ('a' - 38 + i); | ||
32 | } | ||
33 | |||
34 | int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) | ||
35 | { | ||
36 | /* was: x += ... */ | ||
37 | unsigned x = getpid() + monotonic_us(); | ||
38 | do { | ||
39 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame | ||
40 | * (low-order bit is not "random", etc...), | ||
41 | * but for our purposes it is good enough */ | ||
42 | x = x*1664525 + 1013904223; | ||
43 | /* BTW, Park and Miller's "minimal standard generator" is | ||
44 | * x = x*16807 % ((2^31)-1) | ||
45 | * It has no problem with visibly alternating lowest bit | ||
46 | * but is also weak in cryptographic sense + needs div, | ||
47 | * which needs more code (and slower) on many CPUs */ | ||
48 | *p++ = i64c(x >> 16); | ||
49 | *p++ = i64c(x >> 22); | ||
50 | } while (--cnt); | ||
51 | *p = '\0'; | ||
52 | return x; | ||
53 | } | ||
54 | 17 | ||
55 | char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) | 18 | char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) |
56 | { | 19 | { |
57 | int len = 2/2; | 20 | int len = 2 / 2; |
58 | char *salt_ptr = salt; | 21 | char *salt_ptr = salt; |
59 | 22 | ||
60 | /* Standard chpasswd uses uppercase algos ("MD5", not "md5"). | 23 | /* Standard chpasswd uses uppercase algos ("MD5", not "md5"). |
@@ -67,28 +30,61 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) | |||
67 | *salt_ptr++ = '$'; | 30 | *salt_ptr++ = '$'; |
68 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA | 31 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA |
69 | if ((algo[0]|0x20) == 's') { /* sha */ | 32 | if ((algo[0]|0x20) == 's') { /* sha */ |
70 | salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); | 33 | salt[1] = '5' + (strncasecmp(algo, "sha512", 6) == 0); |
71 | len = 16/2; | 34 | len = 16 / 2; |
35 | } | ||
36 | #endif | ||
37 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_YES | ||
38 | if ((algo[0]|0x20) == 'y') { /* yescrypt */ | ||
39 | int rnd; | ||
40 | salt[1] = 'y'; | ||
41 | // The "j9T$" below is the default "yescrypt parameters" encoded by yescrypt_encode_params_r(): | ||
42 | //shadow-4.17.4/src/passwd.c | ||
43 | // salt = crypt_make_salt(NULL, NULL); | ||
44 | //shadow-4.17.4/lib/salt.c | ||
45 | //const char *crypt_make_salt(const char *meth, void *arg) | ||
46 | // if (streq(method, "YESCRYPT")) { | ||
47 | // MAGNUM(result, 'y'); | ||
48 | // salt_len = YESCRYPT_SALT_SIZE; // 24 | ||
49 | // rounds = YESCRYPT_get_salt_cost(arg); // always Y_COST_DEFAULT == 5 for NULL arg | ||
50 | // YESCRYPT_salt_cost_to_buf(result, rounds); // always "j9T$" | ||
51 | // char *retval = crypt_gensalt(result, rounds, NULL, 0); | ||
52 | //libxcrypt-4.4.38/lib/crypt-yescrypt.c | ||
53 | //void gensalt_yescrypt_rn (unsigned long count, | ||
54 | // const uint8_t *rbytes, size_t nrbytes, | ||
55 | // uint8_t *output, size_t o_size) | ||
56 | // yescrypt_params_t params = { | ||
57 | // .flags = YESCRYPT_DEFAULTS, | ||
58 | // .p = 1, | ||
59 | // }; | ||
60 | // if (count < 3) ... else | ||
61 | // params.r = 32; // N in 4KiB | ||
62 | // params.N = 1ULL << (count + 7); // 3 -> 1024, 4 -> 2048, ... 11 -> 262144 | ||
63 | // yescrypt_encode_params_r(¶ms, rbytes, nrbytes, outbuf, o_size) // always "$y$j9T$<random>" | ||
64 | len = 22 / 2; | ||
65 | salt_ptr = stpcpy(salt_ptr, "j9T$"); | ||
66 | /* append 2*len random chars */ | ||
67 | rnd = crypt_make_rand64encoded(salt_ptr, len); | ||
68 | /* fix up last char: it must be in 0..3 range (encoded as one of "./01"). | ||
69 | * IOW: salt_ptr[20..21] encode 16th random byte, must not be > 0xff. | ||
70 | * Without this, we can generate salts which are rejected | ||
71 | * by implementations with more strict salt length check. | ||
72 | */ | ||
73 | salt_ptr[21] = i2a64(rnd & 3); | ||
74 | /* For "mkpasswd -m yescrypt PASS j9T$<salt>" use case, | ||
75 | * "j9T$" is considered part of salt, | ||
76 | * need to return pointer to 'j'. Without -4, | ||
77 | * we'd end up using "j9T$j9T$<salt>" as salt. | ||
78 | */ | ||
79 | return salt_ptr - 4; | ||
72 | } | 80 | } |
73 | #endif | 81 | #endif |
74 | } | 82 | } |
75 | crypt_make_salt(salt_ptr, len); | 83 | crypt_make_rand64encoded(salt_ptr, len); /* appends 2*len random chars */ |
76 | return salt_ptr; | 84 | return salt_ptr; |
77 | } | 85 | } |
78 | 86 | ||
79 | #if ENABLE_USE_BB_CRYPT | 87 | #if ENABLE_USE_BB_CRYPT |
80 | |||
81 | static char* | ||
82 | to64(char *s, unsigned v, int n) | ||
83 | { | ||
84 | while (--n >= 0) { | ||
85 | /* *s++ = ascii64[v & 0x3f]; */ | ||
86 | *s++ = i64c(v); | ||
87 | v >>= 6; | ||
88 | } | ||
89 | return s; | ||
90 | } | ||
91 | |||
92 | /* | 88 | /* |
93 | * DES and MD5 crypt implementations are taken from uclibc. | 89 | * DES and MD5 crypt implementations are taken from uclibc. |
94 | * They were modified to not use static buffers. | 90 | * They were modified to not use static buffers. |
@@ -99,6 +95,9 @@ to64(char *s, unsigned v, int n) | |||
99 | #if ENABLE_USE_BB_CRYPT_SHA | 95 | #if ENABLE_USE_BB_CRYPT_SHA |
100 | #include "pw_encrypt_sha.c" | 96 | #include "pw_encrypt_sha.c" |
101 | #endif | 97 | #endif |
98 | #if ENABLE_USE_BB_CRYPT_YES | ||
99 | #include "pw_encrypt_yes.c" | ||
100 | #endif | ||
102 | 101 | ||
103 | /* Other advanced crypt ids (TODO?): */ | 102 | /* Other advanced crypt ids (TODO?): */ |
104 | /* $2$ or $2a$: Blowfish */ | 103 | /* $2$ or $2a$: Blowfish */ |
@@ -109,7 +108,7 @@ static struct des_ctx *des_ctx; | |||
109 | /* my_crypt returns malloc'ed data */ | 108 | /* my_crypt returns malloc'ed data */ |
110 | static char *my_crypt(const char *key, const char *salt) | 109 | static char *my_crypt(const char *key, const char *salt) |
111 | { | 110 | { |
112 | /* MD5 or SHA? */ | 111 | /* "$x$...." string? */ |
113 | if (salt[0] == '$' && salt[1] && salt[2] == '$') { | 112 | if (salt[0] == '$' && salt[1] && salt[2] == '$') { |
114 | if (salt[1] == '1') | 113 | if (salt[1] == '1') |
115 | return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); | 114 | return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); |
@@ -117,6 +116,10 @@ static char *my_crypt(const char *key, const char *salt) | |||
117 | if (salt[1] == '5' || salt[1] == '6') | 116 | if (salt[1] == '5' || salt[1] == '6') |
118 | return sha_crypt((char*)key, (char*)salt); | 117 | return sha_crypt((char*)key, (char*)salt); |
119 | #endif | 118 | #endif |
119 | #if ENABLE_USE_BB_CRYPT_YES | ||
120 | if (salt[1] == 'y') | ||
121 | return yes_crypt(key, salt); | ||
122 | #endif | ||
120 | } | 123 | } |
121 | 124 | ||
122 | if (!des_cctx) | 125 | if (!des_cctx) |