source: MondoRescue/branches/3.3/mindi-busybox/libbb/pw_encrypt.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 3.5 KB
Line 
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
16static 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
30int 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
51char* 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
77static char*
78to64(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
102static struct const_des_ctx *des_cctx;
103static struct des_ctx *des_ctx;
104
105/* my_crypt returns malloc'ed data */
106static 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 */
125static void my_crypt_cleanup(void)
126{
127 free(des_cctx);
128 free(des_ctx);
129 des_cctx = NULL;
130 des_ctx = NULL;
131}
132
133char* 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
147char* 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
Note: See TracBrowser for help on using the repository browser.