blob: 4cdc2de7635f101111244040ac2e5c16d5c10513
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Utility routines. |
4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | */ |
9 | |
10 | #include "libbb.h" |
11 | |
12 | /* static const uint8_t ascii64[] ALIGN1 = |
13 | * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
14 | */ |
15 | |
16 | static int i64c(int i) |
17 | { |
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 | } |
29 | |
30 | int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) |
31 | { |
32 | /* was: x += ... */ |
33 | int x = getpid() + monotonic_us(); |
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 | |
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; |
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 */ |
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 |
65 | if ((algo[0]|0x20) == 's') { /* sha */ |
66 | salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); |
67 | len = 16/2; |
68 | } |
69 | #endif |
70 | } |
71 | crypt_make_salt(salt_ptr, len); |
72 | return salt_ptr; |
73 | } |
74 | |
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; |
84 | } |
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" |
97 | #endif |
98 | |
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); |
122 | } |
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 | { |
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 : ""); |
157 | } |
158 | |
159 | #endif |
160 |