2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 2.00 of the Zend license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.zend.com/license/2_00.txt. |
12 | If you did not receive a copy of the Zend license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@zend.com so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #include "hphp/zend/zend-string.h"
23 ///////////////////////////////////////////////////////////////////////////////
25 static unsigned char PADDING
[64] = {
26 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31 // F, G, H and I are basic SHA1 functions.
32 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
33 #define G(x, y, z) ((x) ^ (y) ^ (z))
34 #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
35 #define I(x, y, z) ((x) ^ (y) ^ (z))
37 // ROTATE_LEFT rotates x left n bits.
38 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
41 #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
42 (x[i&15]=ROTATE_LEFT(tmp, 1)) )
44 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
45 #define FF(a, b, c, d, e, w) { \
46 (e) += F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \
47 (e) += ROTATE_LEFT ((a), 5); \
48 (b) = ROTATE_LEFT((b), 30); \
50 #define GG(a, b, c, d, e, w) { \
51 (e) += G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \
52 (e) += ROTATE_LEFT ((a), 5); \
53 (b) = ROTATE_LEFT((b), 30); \
55 #define HH(a, b, c, d, e, w) { \
56 (e) += H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \
57 (e) += ROTATE_LEFT ((a), 5); \
58 (b) = ROTATE_LEFT((b), 30); \
60 #define II(a, b, c, d, e, w) { \
61 (e) += I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \
62 (e) += ROTATE_LEFT ((a), 5); \
63 (b) = ROTATE_LEFT((b), 30); \
66 static void SHA1Transform(uint32_t state
[5], const unsigned char block
[64]);
69 * Encodes input (uint32_t) into output (unsigned char). Assumes len is
72 static void SHA1Encode(unsigned char *output
, uint32_t *input
,
76 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
77 output
[j
] = (unsigned char) ((input
[i
] >> 24) & 0xff);
78 output
[j
+ 1] = (unsigned char) ((input
[i
] >> 16) & 0xff);
79 output
[j
+ 2] = (unsigned char) ((input
[i
] >> 8) & 0xff);
80 output
[j
+ 3] = (unsigned char) (input
[i
] & 0xff);
85 * Decodes input (unsigned char) into output (uint32_t). Assumes len is
88 static void SHA1Decode(uint32_t *output
, const unsigned char *input
,
92 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
93 output
[i
] = ((uint32_t) input
[j
+ 3]) | (((uint32_t) input
[j
+ 2]) << 8) |
94 (((uint32_t) input
[j
+ 1]) << 16) | (((uint32_t) input
[j
]) << 24);
100 uint32_t state
[5]; /* state (ABCD) */
101 uint32_t count
[2]; /* number of bits, modulo 2^64 (lsb first) */
102 unsigned char buffer
[64]; /* input buffer */
106 * SHA1 initialization. Begins an SHA1 operation, writing a new context.
108 void PHP_SHA1Init(PHP_SHA1_CTX
* context
) {
109 context
->count
[0] = context
->count
[1] = 0;
110 // Load magic initialization constants.
111 context
->state
[0] = 0x67452301;
112 context
->state
[1] = 0xefcdab89;
113 context
->state
[2] = 0x98badcfe;
114 context
->state
[3] = 0x10325476;
115 context
->state
[4] = 0xc3d2e1f0;
119 * SHA1 block update operation. Continues an SHA1 message-digest
120 * operation, processing another message block, and updating the context.
122 void PHP_SHA1Update(PHP_SHA1_CTX
* context
, const unsigned char *input
,
123 unsigned int inputLen
) {
124 unsigned int i
, index
, partLen
;
126 /* Compute number of bytes mod 64 */
127 index
= (unsigned int) ((context
->count
[0] >> 3) & 0x3F);
129 /* Update number of bits */
130 if ((context
->count
[0] += ((uint32_t) inputLen
<< 3))
131 < ((uint32_t) inputLen
<< 3)) {
134 context
->count
[1] += ((uint32_t) inputLen
>> 29);
136 partLen
= 64 - index
;
138 // Transform as many times as possible.
139 if (inputLen
>= partLen
) {
140 memcpy((unsigned char*) & context
->buffer
[index
],
141 (unsigned char*) input
, partLen
);
142 SHA1Transform(context
->state
, context
->buffer
);
144 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64) {
145 SHA1Transform(context
->state
, &input
[i
]);
152 /* Buffer remaining input */
153 memcpy((unsigned char*) & context
->buffer
[index
],
154 (unsigned char*) & input
[i
], inputLen
- i
);
158 * SHA1 finalization. Ends an SHA1 message-digest operation, writing the
159 * the message digest and zeroizing the context.
161 void PHP_SHA1Final(unsigned char digest
[20], PHP_SHA1_CTX
* context
) {
162 unsigned char bits
[8];
163 unsigned int index
, padLen
;
165 /* Save number of bits */
166 bits
[7] = context
->count
[0] & 0xFF;
167 bits
[6] = (context
->count
[0] >> 8) & 0xFF;
168 bits
[5] = (context
->count
[0] >> 16) & 0xFF;
169 bits
[4] = (context
->count
[0] >> 24) & 0xFF;
170 bits
[3] = context
->count
[1] & 0xFF;
171 bits
[2] = (context
->count
[1] >> 8) & 0xFF;
172 bits
[1] = (context
->count
[1] >> 16) & 0xFF;
173 bits
[0] = (context
->count
[1] >> 24) & 0xFF;
175 // Pad out to 56 mod 64.
176 index
= (unsigned int) ((context
->count
[0] >> 3) & 0x3f);
177 padLen
= (index
< 56) ? (56 - index
) : (120 - index
);
178 PHP_SHA1Update(context
, PADDING
, padLen
);
180 /* Append length (before padding) */
181 PHP_SHA1Update(context
, bits
, 8);
183 /* Store state in digest */
184 SHA1Encode(digest
, context
->state
, 20);
186 // Zeroize sensitive information.
187 memset((unsigned char*) context
, 0, sizeof(*context
));
191 * SHA1 basic transformation. Transforms state based on block.
193 static void SHA1Transform(uint32_t state
[5], const unsigned char block
[64]) {
194 uint32_t a
= state
[0], b
= state
[1], c
= state
[2];
195 uint32_t d
= state
[3], e
= state
[4], x
[16], tmp
;
197 SHA1Decode(x
, block
, 64);
200 FF(a
, b
, c
, d
, e
, x
[0]); /* 1 */
201 FF(e
, a
, b
, c
, d
, x
[1]); /* 2 */
202 FF(d
, e
, a
, b
, c
, x
[2]); /* 3 */
203 FF(c
, d
, e
, a
, b
, x
[3]); /* 4 */
204 FF(b
, c
, d
, e
, a
, x
[4]); /* 5 */
205 FF(a
, b
, c
, d
, e
, x
[5]); /* 6 */
206 FF(e
, a
, b
, c
, d
, x
[6]); /* 7 */
207 FF(d
, e
, a
, b
, c
, x
[7]); /* 8 */
208 FF(c
, d
, e
, a
, b
, x
[8]); /* 9 */
209 FF(b
, c
, d
, e
, a
, x
[9]); /* 10 */
210 FF(a
, b
, c
, d
, e
, x
[10]); /* 11 */
211 FF(e
, a
, b
, c
, d
, x
[11]); /* 12 */
212 FF(d
, e
, a
, b
, c
, x
[12]); /* 13 */
213 FF(c
, d
, e
, a
, b
, x
[13]); /* 14 */
214 FF(b
, c
, d
, e
, a
, x
[14]); /* 15 */
215 FF(a
, b
, c
, d
, e
, x
[15]); /* 16 */
216 FF(e
, a
, b
, c
, d
, W(16)); /* 17 */
217 FF(d
, e
, a
, b
, c
, W(17)); /* 18 */
218 FF(c
, d
, e
, a
, b
, W(18)); /* 19 */
219 FF(b
, c
, d
, e
, a
, W(19)); /* 20 */
222 GG(a
, b
, c
, d
, e
, W(20)); /* 21 */
223 GG(e
, a
, b
, c
, d
, W(21)); /* 22 */
224 GG(d
, e
, a
, b
, c
, W(22)); /* 23 */
225 GG(c
, d
, e
, a
, b
, W(23)); /* 24 */
226 GG(b
, c
, d
, e
, a
, W(24)); /* 25 */
227 GG(a
, b
, c
, d
, e
, W(25)); /* 26 */
228 GG(e
, a
, b
, c
, d
, W(26)); /* 27 */
229 GG(d
, e
, a
, b
, c
, W(27)); /* 28 */
230 GG(c
, d
, e
, a
, b
, W(28)); /* 29 */
231 GG(b
, c
, d
, e
, a
, W(29)); /* 30 */
232 GG(a
, b
, c
, d
, e
, W(30)); /* 31 */
233 GG(e
, a
, b
, c
, d
, W(31)); /* 32 */
234 GG(d
, e
, a
, b
, c
, W(32)); /* 33 */
235 GG(c
, d
, e
, a
, b
, W(33)); /* 34 */
236 GG(b
, c
, d
, e
, a
, W(34)); /* 35 */
237 GG(a
, b
, c
, d
, e
, W(35)); /* 36 */
238 GG(e
, a
, b
, c
, d
, W(36)); /* 37 */
239 GG(d
, e
, a
, b
, c
, W(37)); /* 38 */
240 GG(c
, d
, e
, a
, b
, W(38)); /* 39 */
241 GG(b
, c
, d
, e
, a
, W(39)); /* 40 */
244 HH(a
, b
, c
, d
, e
, W(40)); /* 41 */
245 HH(e
, a
, b
, c
, d
, W(41)); /* 42 */
246 HH(d
, e
, a
, b
, c
, W(42)); /* 43 */
247 HH(c
, d
, e
, a
, b
, W(43)); /* 44 */
248 HH(b
, c
, d
, e
, a
, W(44)); /* 45 */
249 HH(a
, b
, c
, d
, e
, W(45)); /* 46 */
250 HH(e
, a
, b
, c
, d
, W(46)); /* 47 */
251 HH(d
, e
, a
, b
, c
, W(47)); /* 48 */
252 HH(c
, d
, e
, a
, b
, W(48)); /* 49 */
253 HH(b
, c
, d
, e
, a
, W(49)); /* 50 */
254 HH(a
, b
, c
, d
, e
, W(50)); /* 51 */
255 HH(e
, a
, b
, c
, d
, W(51)); /* 52 */
256 HH(d
, e
, a
, b
, c
, W(52)); /* 53 */
257 HH(c
, d
, e
, a
, b
, W(53)); /* 54 */
258 HH(b
, c
, d
, e
, a
, W(54)); /* 55 */
259 HH(a
, b
, c
, d
, e
, W(55)); /* 56 */
260 HH(e
, a
, b
, c
, d
, W(56)); /* 57 */
261 HH(d
, e
, a
, b
, c
, W(57)); /* 58 */
262 HH(c
, d
, e
, a
, b
, W(58)); /* 59 */
263 HH(b
, c
, d
, e
, a
, W(59)); /* 60 */
266 II(a
, b
, c
, d
, e
, W(60)); /* 61 */
267 II(e
, a
, b
, c
, d
, W(61)); /* 62 */
268 II(d
, e
, a
, b
, c
, W(62)); /* 63 */
269 II(c
, d
, e
, a
, b
, W(63)); /* 64 */
270 II(b
, c
, d
, e
, a
, W(64)); /* 65 */
271 II(a
, b
, c
, d
, e
, W(65)); /* 66 */
272 II(e
, a
, b
, c
, d
, W(66)); /* 67 */
273 II(d
, e
, a
, b
, c
, W(67)); /* 68 */
274 II(c
, d
, e
, a
, b
, W(68)); /* 69 */
275 II(b
, c
, d
, e
, a
, W(69)); /* 70 */
276 II(a
, b
, c
, d
, e
, W(70)); /* 71 */
277 II(e
, a
, b
, c
, d
, W(71)); /* 72 */
278 II(d
, e
, a
, b
, c
, W(72)); /* 73 */
279 II(c
, d
, e
, a
, b
, W(73)); /* 74 */
280 II(b
, c
, d
, e
, a
, W(74)); /* 75 */
281 II(a
, b
, c
, d
, e
, W(75)); /* 76 */
282 II(e
, a
, b
, c
, d
, W(76)); /* 77 */
283 II(d
, e
, a
, b
, c
, W(77)); /* 78 */
284 II(c
, d
, e
, a
, b
, W(78)); /* 79 */
285 II(b
, c
, d
, e
, a
, W(79)); /* 80 */
293 /* Zeroize sensitive information. */
294 memset((unsigned char*) x
, 0, sizeof(x
));
297 ///////////////////////////////////////////////////////////////////////////////
299 char *string_sha1(const char *arg
, int arg_len
, bool raw
, int &out_len
) {
300 PHP_SHA1_CTX context
;
301 unsigned char digest
[20];
303 PHP_SHA1Init(&context
);
304 PHP_SHA1Update(&context
, (const unsigned char *)arg
, arg_len
);
305 PHP_SHA1Final(digest
, &context
);
308 return string_duplicate((const char *)digest
, 20);
312 return string_bin2hex((const char*)digest
, out_len
);
315 ///////////////////////////////////////////////////////////////////////////////