Skip to content

Commit 19d3e29

Browse files
committed
Clean house in cryptographic hashing code
- Remove dead code from php_crypt_r.c This code has been commented out since the file was added in 2008. It's safe to say that no-one is ever going to use it. - Fix typo in comment in php_crypt_r.c - Remove redundant Windows-only implementation of php_md5_crypt_r There is a portable implementation in the same file, which is selected if not building for Windows. But why should Windows have its own special implementation of this function at all? There doesn't seem to be any good reason. Better to use the portable implementation on all platforms. - Don't define useless __CONST macro in php_crypt_r.h This preprocessor macro is not used anywhere. - Add comment on functions for encoding data as Base64 - Remove dead code from crypt_blowfish.h - Remove unneeded junk comments from crypt_freesec.c - Remove dead code from crypt_blowfish.c This function has been commented out since 2011.
1 parent e94afec commit 19d3e29

File tree

6 files changed

+6
-262
lines changed

6 files changed

+6
-262
lines changed

ext/standard/crypt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ PHP_MSHUTDOWN_FUNCTION(crypt) /* {{{ */
8181

8282
static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
8383

84+
/* Encode a string of bytes as Base64 */
8485
static void php_to64(char *s, int n) /* {{{ */
8586
{
8687
while (--n >= 0) {

ext/standard/crypt_blowfish.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -872,33 +872,3 @@ char *php_crypt_blowfish_rn(const char *key, const char *setting,
872872
__set_errno(EINVAL); /* pretend we don't support this hash type */
873873
return NULL;
874874
}
875-
876-
#if 0
877-
char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
878-
const char *input, int size, char *output, int output_size)
879-
{
880-
if (size < 16 || output_size < 7 + 22 + 1 ||
881-
(count && (count < 4 || count > 31)) ||
882-
prefix[0] != '$' || prefix[1] != '2' ||
883-
(prefix[2] != 'a' && prefix[2] != 'b' && prefix[2] != 'y')) {
884-
if (output_size > 0) output[0] = '\0';
885-
__set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
886-
return NULL;
887-
}
888-
889-
if (!count) count = 5;
890-
891-
output[0] = '$';
892-
output[1] = '2';
893-
output[2] = prefix[2];
894-
output[3] = '$';
895-
output[4] = '0' + count / 10;
896-
output[5] = '0' + count % 10;
897-
output[6] = '$';
898-
899-
BF_encode(&output[7], (const BF_word *)input, 16);
900-
output[7 + 22] = '\0';
901-
902-
return output;
903-
}
904-
#endif

ext/standard/crypt_blowfish.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,7 @@
1717
#ifndef _CRYPT_BLOWFISH_H
1818
#define _CRYPT_BLOWFISH_H
1919

20-
#if 0
21-
extern int _crypt_output_magic(const char *setting, char *output, int size);
22-
#endif
2320
extern char *php_crypt_blowfish_rn(const char *key, const char *setting,
2421
char *output, int size);
25-
#if 0
26-
extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
27-
unsigned long count,
28-
const char *input, int size, char *output, int output_size);
29-
#endif
3022

3123
#endif

ext/standard/crypt_freesec.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,6 @@ static const u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
170170

171171
static const unsigned char ascii64[] =
172172
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
173-
/* 0000000000111111111122222222223333333333444444444455555555556666 */
174-
/* 0123456789012345678901234567890123456789012345678901234567890123 */
175173

176174
static u_char m_sbox[4][4096];
177175
static uint32_t psbox[4][256];

ext/standard/php_crypt_r.c

Lines changed: 3 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,12 @@
4141

4242
#include "php_crypt_r.h"
4343
#include "crypt_freesec.h"
44-
45-
#if !PHP_WIN32
4644
#include "ext/standard/md5.h"
47-
#endif
4845

4946
#ifdef ZTS
5047
MUTEX_T php_crypt_extended_init_lock;
5148
#endif
5249

53-
/* TODO: enable it when enabling vista/2k8 mode in tsrm */
54-
#if 0
55-
CONDITION_VARIABLE initialized;
56-
#endif
57-
5850
void php_init_crypt_r()
5951
{
6052
#ifdef ZTS
@@ -87,210 +79,22 @@ void _crypt_extended_init_r(void)
8779
#endif
8880
}
8981

90-
/* MD% crypt implementation using the windows CryptoApi */
82+
/* MD5 crypt implementation using the windows CryptoApi */
9183
#define MD5_MAGIC "$1$"
9284
#define MD5_MAGIC_LEN 3
9385

9486
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
9587
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
9688

97-
static void
98-
to64(char *s, int32_t v, int n)
89+
/* Convert a 16/32 bit integer to Base64 string representation */
90+
static void to64(char *s, int32_t v, int n)
9991
{
10092
while (--n >= 0) {
10193
*s++ = itoa64[v & 0x3f];
10294
v >>= 6;
10395
}
10496
}
10597

106-
#ifdef PHP_WIN32
107-
char * php_md5_crypt_r(const char *pw, const char *salt, char *out) {
108-
HCRYPTPROV hCryptProv;
109-
HCRYPTHASH ctx, ctx1;
110-
DWORD i, pwl, sl;
111-
const BYTE magic_md5[4] = "$1$";
112-
const DWORD magic_md5_len = 3;
113-
DWORD dwHashLen;
114-
int pl;
115-
__int32 l;
116-
const char *sp = salt;
117-
const char *ep = salt;
118-
char *p = NULL;
119-
char *passwd = out;
120-
unsigned char final[16];
121-
122-
/* Acquire a cryptographic provider context handle. */
123-
if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
124-
return NULL;
125-
}
126-
127-
pwl = (DWORD) strlen(pw);
128-
129-
/* Refine the salt first */
130-
sp = salt;
131-
132-
/* If it starts with the magic string, then skip that */
133-
if (strncmp(sp, MD5_MAGIC, MD5_MAGIC_LEN) == 0) {
134-
sp += MD5_MAGIC_LEN;
135-
}
136-
137-
/* It stops at the first '$', max 8 chars */
138-
for (ep = sp; *ep != '\0' && *ep != '$' && ep < (sp + 8); ep++);
139-
140-
/* get the length of the true salt */
141-
sl = (DWORD)(ep - sp);
142-
143-
/* Create an empty hash object. */
144-
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx)) {
145-
goto _destroyProv;
146-
}
147-
148-
/* The password first, since that is what is most unknown */
149-
if(!CryptHashData(ctx, (BYTE *)pw, pwl, 0)) {
150-
goto _destroyCtx0;
151-
}
152-
153-
/* Then our magic string */
154-
if(!CryptHashData(ctx, magic_md5, magic_md5_len, 0)) {
155-
goto _destroyCtx0;
156-
}
157-
158-
/* Then the raw salt */
159-
if(!CryptHashData( ctx, (BYTE *)sp, sl, 0)) {
160-
goto _destroyCtx0;
161-
}
162-
163-
/* MD5(pw,salt,pw), valid. */
164-
/* Then just as many characters of the MD5(pw,salt,pw) */
165-
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx1)) {
166-
goto _destroyCtx0;
167-
}
168-
if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) {
169-
goto _destroyCtx1;
170-
}
171-
if(!CryptHashData(ctx1, (BYTE *)sp, sl, 0)) {
172-
goto _destroyCtx1;
173-
}
174-
if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) {
175-
goto _destroyCtx1;
176-
}
177-
178-
dwHashLen = 16;
179-
CryptGetHashParam(ctx1, HP_HASHVAL, final, &dwHashLen, 0);
180-
/* MD5(pw,salt,pw). Valid. */
181-
182-
for (pl = pwl; pl > 0; pl -= 16) {
183-
CryptHashData(ctx, final, (DWORD)(pl > 16 ? 16 : pl), 0);
184-
}
185-
186-
/* Don't leave anything around in vm they could use. */
187-
ZEND_SECURE_ZERO(final, sizeof(final));
188-
189-
/* Then something really weird... */
190-
for (i = pwl; i != 0; i >>= 1) {
191-
if ((i & 1) != 0) {
192-
CryptHashData(ctx, (const BYTE *)final, 1, 0);
193-
} else {
194-
CryptHashData(ctx, (const BYTE *)pw, 1, 0);
195-
}
196-
}
197-
198-
memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN);
199-
200-
if (strncpy_s(passwd + MD5_MAGIC_LEN, MD5_HASH_MAX_LEN - MD5_MAGIC_LEN, sp, sl + 1) != 0) {
201-
goto _destroyCtx1;
202-
}
203-
passwd[MD5_MAGIC_LEN + sl] = '\0';
204-
strcat_s(passwd, MD5_HASH_MAX_LEN, "$");
205-
206-
dwHashLen = 16;
207-
208-
/* Fetch the ctx hash value */
209-
CryptGetHashParam(ctx, HP_HASHVAL, final, &dwHashLen, 0);
210-
211-
for (i = 0; i < 1000; i++) {
212-
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx1)) {
213-
goto _destroyCtx1;
214-
}
215-
216-
if ((i & 1) != 0) {
217-
if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) {
218-
goto _destroyCtx1;
219-
}
220-
} else {
221-
if(!CryptHashData(ctx1, (BYTE *)final, 16, 0)) {
222-
goto _destroyCtx1;
223-
}
224-
}
225-
226-
if ((i % 3) != 0) {
227-
if(!CryptHashData(ctx1, (BYTE *)sp, sl, 0)) {
228-
goto _destroyCtx1;
229-
}
230-
}
231-
232-
if ((i % 7) != 0) {
233-
if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) {
234-
goto _destroyCtx1;
235-
}
236-
}
237-
238-
if ((i & 1) != 0) {
239-
if(!CryptHashData(ctx1, (BYTE *)final, 16, 0)) {
240-
goto _destroyCtx1;
241-
}
242-
} else {
243-
if(!CryptHashData(ctx1, (BYTE *)pw, pwl, 0)) {
244-
goto _destroyCtx1;
245-
}
246-
}
247-
248-
/* Fetch the ctx hash value */
249-
dwHashLen = 16;
250-
CryptGetHashParam(ctx1, HP_HASHVAL, final, &dwHashLen, 0);
251-
if(!(CryptDestroyHash(ctx1))) {
252-
goto _destroyCtx0;
253-
}
254-
}
255-
256-
ctx1 = (HCRYPTHASH) NULL;
257-
258-
p = passwd + sl + MD5_MAGIC_LEN + 1;
259-
260-
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
261-
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
262-
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
263-
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
264-
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
265-
l = final[11]; to64(p,l,2); p += 2;
266-
267-
*p = '\0';
268-
269-
ZEND_SECURE_ZERO(final, sizeof(final));
270-
271-
272-
_destroyCtx1:
273-
if (ctx1) {
274-
if (!CryptDestroyHash(ctx1)) {
275-
276-
}
277-
}
278-
279-
_destroyCtx0:
280-
CryptDestroyHash(ctx);
281-
282-
_destroyProv:
283-
/* Release the provider handle.*/
284-
if(hCryptProv) {
285-
if(!(CryptReleaseContext(hCryptProv, 0))) {
286-
return NULL;
287-
}
288-
}
289-
290-
return out;
291-
}
292-
#else
293-
29498
/*
29599
* MD5 password encryption.
296100
*/
@@ -398,7 +202,3 @@ char * php_md5_crypt_r(const char *pw, const char *salt, char *out)
398202
ZEND_SECURE_ZERO(final, sizeof(final));
399203
return (passwd);
400204
}
401-
402-
#undef MD5_MAGIC
403-
#undef MD5_MAGIC_LEN
404-
#endif

ext/standard/php_crypt_r.h

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,14 @@
1717
#ifndef _CRYPT_WIHN32_H_
1818
#define _CRYPT_WIHN32_H_
1919

20-
#ifdef __cplusplus
21-
extern "C"
22-
{
23-
#endif
20+
BEGIN_EXTERN_C()
2421
#include "crypt_freesec.h"
2522

26-
#ifndef __const
27-
#ifdef __GNUC__
28-
#define __CONST __const
29-
#else
30-
#define __CONST
31-
#endif
32-
#else
33-
#define __CONST __const
34-
#endif
35-
3623
void php_init_crypt_r();
3724
void php_shutdown_crypt_r();
3825

3926
extern void _crypt_extended_init_r(void);
4027

41-
/*PHPAPI char* crypt(const char *key, const char *salt);*/
4228
PHPAPI char *php_crypt_r (const char *__key, const char *__salt, struct php_crypt_extended_data * __data);
4329

4430
#define MD5_HASH_MAX_LEN 120
@@ -48,9 +34,6 @@ PHPAPI char *php_crypt_r (const char *__key, const char *__salt, struct php_cryp
4834
extern char * php_md5_crypt_r(const char *pw, const char *salt, char *out);
4935
extern char * php_sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen);
5036
extern char * php_sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen);
51-
52-
#ifdef __cplusplus
53-
}
54-
#endif
37+
END_EXTERN_C()
5538

5639
#endif /* _CRYPT_WIHN32_H_ */

0 commit comments

Comments
 (0)