blob: 39ffa084f29a81ce2817e15a9547a0e9d3fb74a8
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[] = |
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 | if (algo[0] != 'd') { /* not des */ |
56 | len = 8/2; /* so far assuming md5 */ |
57 | *salt_ptr++ = '$'; |
58 | *salt_ptr++ = '1'; |
59 | *salt_ptr++ = '$'; |
60 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA |
61 | if (algo[0] == 's') { /* sha */ |
62 | salt[1] = '5' + (strcmp(algo, "sha512") == 0); |
63 | len = 16/2; |
64 | } |
65 | #endif |
66 | } |
67 | crypt_make_salt(salt_ptr, len); |
68 | return salt_ptr; |
69 | } |
70 | |
71 | #if ENABLE_USE_BB_CRYPT |
72 | |
73 | static char* |
74 | to64(char *s, unsigned v, int n) |
75 | { |
76 | while (--n >= 0) { |
77 | /* *s++ = ascii64[v & 0x3f]; */ |
78 | *s++ = i64c(v); |
79 | v >>= 6; |
80 | } |
81 | return s; |
82 | } |
83 | |
84 | /* |
85 | * DES and MD5 crypt implementations are taken from uclibc. |
86 | * They were modified to not use static buffers. |
87 | */ |
88 | |
89 | #include "pw_encrypt_des.c" |
90 | #include "pw_encrypt_md5.c" |
91 | #if ENABLE_USE_BB_CRYPT_SHA |
92 | #include "pw_encrypt_sha.c" |
93 | #endif |
94 | |
95 | /* Other advanced crypt ids (TODO?): */ |
96 | /* $2$ or $2a$: Blowfish */ |
97 | |
98 | static struct const_des_ctx *des_cctx; |
99 | static struct des_ctx *des_ctx; |
100 | |
101 | /* my_crypt returns malloc'ed data */ |
102 | static char *my_crypt(const char *key, const char *salt) |
103 | { |
104 | /* MD5 or SHA? */ |
105 | if (salt[0] == '$' && salt[1] && salt[2] == '$') { |
106 | if (salt[1] == '1') |
107 | return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); |
108 | #if ENABLE_USE_BB_CRYPT_SHA |
109 | if (salt[1] == '5' || salt[1] == '6') |
110 | return sha_crypt((char*)key, (char*)salt); |
111 | #endif |
112 | } |
113 | |
114 | if (!des_cctx) |
115 | des_cctx = const_des_init(); |
116 | des_ctx = des_init(des_ctx, des_cctx); |
117 | return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); |
118 | } |
119 | |
120 | /* So far nobody wants to have it public */ |
121 | static void my_crypt_cleanup(void) |
122 | { |
123 | free(des_cctx); |
124 | free(des_ctx); |
125 | des_cctx = NULL; |
126 | des_ctx = NULL; |
127 | } |
128 | |
129 | char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) |
130 | { |
131 | char *encrypted; |
132 | |
133 | encrypted = my_crypt(clear, salt); |
134 | |
135 | if (cleanup) |
136 | my_crypt_cleanup(); |
137 | |
138 | return encrypted; |
139 | } |
140 | |
141 | #else /* if !ENABLE_USE_BB_CRYPT */ |
142 | |
143 | char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) |
144 | { |
145 | return xstrdup(crypt(clear, salt)); |
146 | } |
147 | |
148 | #endif |
149 |