aboutsummaryrefslogtreecommitdiff
path: root/libbb/pw_encrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/pw_encrypt.c')
-rw-r--r--libbb/pw_encrypt.c113
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
20static 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
34int 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
55char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) 18char* 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(&params, 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
81static char*
82to64(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 */
110static char *my_crypt(const char *key, const char *salt) 109static 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)