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 #include <folly/ScopeGuard.h>
26 ///////////////////////////////////////////////////////////////////////////////
28 static unsigned char PADDING
[64] = {
29 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
34 // F, G, H and I are basic SHA1 functions.
35 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
36 #define G(x, y, z) ((x) ^ (y) ^ (z))
37 #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
38 #define I(x, y, z) ((x) ^ (y) ^ (z))
40 // ROTATE_LEFT rotates x left n bits.
41 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
44 #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
45 (x[i&15]=ROTATE_LEFT(tmp, 1)) )
47 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
48 #define FF(a, b, c, d, e, w) { \
49 (e) += F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \
50 (e) += ROTATE_LEFT ((a), 5); \
51 (b) = ROTATE_LEFT((b), 30); \
53 #define GG(a, b, c, d, e, w) { \
54 (e) += G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \
55 (e) += ROTATE_LEFT ((a), 5); \
56 (b) = ROTATE_LEFT((b), 30); \
58 #define HH(a, b, c, d, e, w) { \
59 (e) += H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \
60 (e) += ROTATE_LEFT ((a), 5); \
61 (b) = ROTATE_LEFT((b), 30); \
63 #define II(a, b, c, d, e, w) { \
64 (e) += I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \
65 (e) += ROTATE_LEFT ((a), 5); \
66 (b) = ROTATE_LEFT((b), 30); \
69 static void SHA1Transform(uint32_t state
[5], const unsigned char block
[64]);
72 * Encodes input (uint32_t) into output (unsigned char). Assumes len is
75 static void SHA1Encode(unsigned char *output
, uint32_t *input
,
79 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
80 output
[j
] = (unsigned char) ((input
[i
] >> 24) & 0xff);
81 output
[j
+ 1] = (unsigned char) ((input
[i
] >> 16) & 0xff);
82 output
[j
+ 2] = (unsigned char) ((input
[i
] >> 8) & 0xff);
83 output
[j
+ 3] = (unsigned char) (input
[i
] & 0xff);
88 * Decodes input (unsigned char) into output (uint32_t). Assumes len is
91 static void SHA1Decode(uint32_t *output
, const unsigned char *input
,
95 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
96 output
[i
] = ((uint32_t) input
[j
+ 3]) | (((uint32_t) input
[j
+ 2]) << 8) |
97 (((uint32_t) input
[j
+ 1]) << 16) | (((uint32_t) input
[j
]) << 24);
103 uint32_t state
[5]; /* state (ABCD) */
104 uint32_t count
[2]; /* number of bits, modulo 2^64 (lsb first) */
105 unsigned char buffer
[64]; /* input buffer */
109 * SHA1 initialization. Begins an SHA1 operation, writing a new context.
111 void PHP_SHA1Init(PHP_SHA1_CTX
* context
) {
112 context
->count
[0] = context
->count
[1] = 0;
113 // Load magic initialization constants.
114 context
->state
[0] = 0x67452301;
115 context
->state
[1] = 0xefcdab89;
116 context
->state
[2] = 0x98badcfe;
117 context
->state
[3] = 0x10325476;
118 context
->state
[4] = 0xc3d2e1f0;
122 * SHA1 block update operation. Continues an SHA1 message-digest
123 * operation, processing another message block, and updating the context.
125 void PHP_SHA1Update(PHP_SHA1_CTX
* context
, const unsigned char *input
,
126 unsigned int inputLen
) {
127 unsigned int i
, index
, partLen
;
129 /* Compute number of bytes mod 64 */
130 index
= (unsigned int) ((context
->count
[0] >> 3) & 0x3F);
132 /* Update number of bits */
133 if ((context
->count
[0] += ((uint32_t) inputLen
<< 3))
134 < ((uint32_t) inputLen
<< 3)) {
137 context
->count
[1] += ((uint32_t) inputLen
>> 29);
139 partLen
= 64 - index
;
141 // Transform as many times as possible.
142 if (inputLen
>= partLen
) {
143 memcpy((unsigned char*) & context
->buffer
[index
],
144 (unsigned char*) input
, partLen
);
145 SHA1Transform(context
->state
, context
->buffer
);
147 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64) {
148 SHA1Transform(context
->state
, &input
[i
]);
155 /* Buffer remaining input */
156 memcpy((unsigned char*) & context
->buffer
[index
],
157 (unsigned char*) & input
[i
], inputLen
- i
);
161 * SHA1 finalization. Ends an SHA1 message-digest operation, writing the
162 * the message digest and zeroizing the context.
164 void PHP_SHA1Final(unsigned char digest
[20], PHP_SHA1_CTX
* context
) {
165 unsigned char bits
[8];
166 unsigned int index
, padLen
;
168 /* Save number of bits */
169 bits
[7] = context
->count
[0] & 0xFF;
170 bits
[6] = (context
->count
[0] >> 8) & 0xFF;
171 bits
[5] = (context
->count
[0] >> 16) & 0xFF;
172 bits
[4] = (context
->count
[0] >> 24) & 0xFF;
173 bits
[3] = context
->count
[1] & 0xFF;
174 bits
[2] = (context
->count
[1] >> 8) & 0xFF;
175 bits
[1] = (context
->count
[1] >> 16) & 0xFF;
176 bits
[0] = (context
->count
[1] >> 24) & 0xFF;
178 // Pad out to 56 mod 64.
179 index
= (unsigned int) ((context
->count
[0] >> 3) & 0x3f);
180 padLen
= (index
< 56) ? (56 - index
) : (120 - index
);
181 PHP_SHA1Update(context
, PADDING
, padLen
);
183 /* Append length (before padding) */
184 PHP_SHA1Update(context
, bits
, 8);
186 /* Store state in digest */
187 SHA1Encode(digest
, context
->state
, 20);
189 // Zeroize sensitive information.
190 memset((unsigned char*) context
, 0, sizeof(*context
));
194 * SHA1 basic transformation. Transforms state based on block.
196 static void SHA1Transform(uint32_t state
[5], const unsigned char block
[64]) {
197 uint32_t a
= state
[0], b
= state
[1], c
= state
[2];
198 uint32_t d
= state
[3], e
= state
[4], x
[16], tmp
;
200 SHA1Decode(x
, block
, 64);
203 FF(a
, b
, c
, d
, e
, x
[0]); /* 1 */
204 FF(e
, a
, b
, c
, d
, x
[1]); /* 2 */
205 FF(d
, e
, a
, b
, c
, x
[2]); /* 3 */
206 FF(c
, d
, e
, a
, b
, x
[3]); /* 4 */
207 FF(b
, c
, d
, e
, a
, x
[4]); /* 5 */
208 FF(a
, b
, c
, d
, e
, x
[5]); /* 6 */
209 FF(e
, a
, b
, c
, d
, x
[6]); /* 7 */
210 FF(d
, e
, a
, b
, c
, x
[7]); /* 8 */
211 FF(c
, d
, e
, a
, b
, x
[8]); /* 9 */
212 FF(b
, c
, d
, e
, a
, x
[9]); /* 10 */
213 FF(a
, b
, c
, d
, e
, x
[10]); /* 11 */
214 FF(e
, a
, b
, c
, d
, x
[11]); /* 12 */
215 FF(d
, e
, a
, b
, c
, x
[12]); /* 13 */
216 FF(c
, d
, e
, a
, b
, x
[13]); /* 14 */
217 FF(b
, c
, d
, e
, a
, x
[14]); /* 15 */
218 FF(a
, b
, c
, d
, e
, x
[15]); /* 16 */
219 FF(e
, a
, b
, c
, d
, W(16)); /* 17 */
220 FF(d
, e
, a
, b
, c
, W(17)); /* 18 */
221 FF(c
, d
, e
, a
, b
, W(18)); /* 19 */
222 FF(b
, c
, d
, e
, a
, W(19)); /* 20 */
225 GG(a
, b
, c
, d
, e
, W(20)); /* 21 */
226 GG(e
, a
, b
, c
, d
, W(21)); /* 22 */
227 GG(d
, e
, a
, b
, c
, W(22)); /* 23 */
228 GG(c
, d
, e
, a
, b
, W(23)); /* 24 */
229 GG(b
, c
, d
, e
, a
, W(24)); /* 25 */
230 GG(a
, b
, c
, d
, e
, W(25)); /* 26 */
231 GG(e
, a
, b
, c
, d
, W(26)); /* 27 */
232 GG(d
, e
, a
, b
, c
, W(27)); /* 28 */
233 GG(c
, d
, e
, a
, b
, W(28)); /* 29 */
234 GG(b
, c
, d
, e
, a
, W(29)); /* 30 */
235 GG(a
, b
, c
, d
, e
, W(30)); /* 31 */
236 GG(e
, a
, b
, c
, d
, W(31)); /* 32 */
237 GG(d
, e
, a
, b
, c
, W(32)); /* 33 */
238 GG(c
, d
, e
, a
, b
, W(33)); /* 34 */
239 GG(b
, c
, d
, e
, a
, W(34)); /* 35 */
240 GG(a
, b
, c
, d
, e
, W(35)); /* 36 */
241 GG(e
, a
, b
, c
, d
, W(36)); /* 37 */
242 GG(d
, e
, a
, b
, c
, W(37)); /* 38 */
243 GG(c
, d
, e
, a
, b
, W(38)); /* 39 */
244 GG(b
, c
, d
, e
, a
, W(39)); /* 40 */
247 HH(a
, b
, c
, d
, e
, W(40)); /* 41 */
248 HH(e
, a
, b
, c
, d
, W(41)); /* 42 */
249 HH(d
, e
, a
, b
, c
, W(42)); /* 43 */
250 HH(c
, d
, e
, a
, b
, W(43)); /* 44 */
251 HH(b
, c
, d
, e
, a
, W(44)); /* 45 */
252 HH(a
, b
, c
, d
, e
, W(45)); /* 46 */
253 HH(e
, a
, b
, c
, d
, W(46)); /* 47 */
254 HH(d
, e
, a
, b
, c
, W(47)); /* 48 */
255 HH(c
, d
, e
, a
, b
, W(48)); /* 49 */
256 HH(b
, c
, d
, e
, a
, W(49)); /* 50 */
257 HH(a
, b
, c
, d
, e
, W(50)); /* 51 */
258 HH(e
, a
, b
, c
, d
, W(51)); /* 52 */
259 HH(d
, e
, a
, b
, c
, W(52)); /* 53 */
260 HH(c
, d
, e
, a
, b
, W(53)); /* 54 */
261 HH(b
, c
, d
, e
, a
, W(54)); /* 55 */
262 HH(a
, b
, c
, d
, e
, W(55)); /* 56 */
263 HH(e
, a
, b
, c
, d
, W(56)); /* 57 */
264 HH(d
, e
, a
, b
, c
, W(57)); /* 58 */
265 HH(c
, d
, e
, a
, b
, W(58)); /* 59 */
266 HH(b
, c
, d
, e
, a
, W(59)); /* 60 */
269 II(a
, b
, c
, d
, e
, W(60)); /* 61 */
270 II(e
, a
, b
, c
, d
, W(61)); /* 62 */
271 II(d
, e
, a
, b
, c
, W(62)); /* 63 */
272 II(c
, d
, e
, a
, b
, W(63)); /* 64 */
273 II(b
, c
, d
, e
, a
, W(64)); /* 65 */
274 II(a
, b
, c
, d
, e
, W(65)); /* 66 */
275 II(e
, a
, b
, c
, d
, W(66)); /* 67 */
276 II(d
, e
, a
, b
, c
, W(67)); /* 68 */
277 II(c
, d
, e
, a
, b
, W(68)); /* 69 */
278 II(b
, c
, d
, e
, a
, W(69)); /* 70 */
279 II(a
, b
, c
, d
, e
, W(70)); /* 71 */
280 II(e
, a
, b
, c
, d
, W(71)); /* 72 */
281 II(d
, e
, a
, b
, c
, W(72)); /* 73 */
282 II(c
, d
, e
, a
, b
, W(73)); /* 74 */
283 II(b
, c
, d
, e
, a
, W(74)); /* 75 */
284 II(a
, b
, c
, d
, e
, W(75)); /* 76 */
285 II(e
, a
, b
, c
, d
, W(76)); /* 77 */
286 II(d
, e
, a
, b
, c
, W(77)); /* 78 */
287 II(c
, d
, e
, a
, b
, W(78)); /* 79 */
288 II(b
, c
, d
, e
, a
, W(79)); /* 80 */
296 /* Zeroize sensitive information. */
297 memset((unsigned char*) x
, 0, sizeof(x
));
300 ///////////////////////////////////////////////////////////////////////////////
302 std::string
string_sha1(folly::StringPiece s
) {
304 auto const hex
= string_sha1(s
.data(), s
.size(), false, out_len
);
305 SCOPE_EXIT
{ free(hex
); };
307 return std::string(hex
, out_len
);
310 char *string_sha1(const char *arg
, int arg_len
, bool raw
, int &out_len
) {
311 PHP_SHA1_CTX context
;
312 unsigned char digest
[20];
314 PHP_SHA1Init(&context
);
315 PHP_SHA1Update(&context
, (const unsigned char *)arg
, arg_len
);
316 PHP_SHA1Final(digest
, &context
);
319 return string_duplicate((const char *)digest
, 20);
323 return string_bin2hex((const char*)digest
, out_len
);
326 ///////////////////////////////////////////////////////////////////////////////