PageRenderTime 70ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/standard/md5.c

https://bitbucket.org/wmark/php-fpm-0.5
C | 440 lines | 264 code | 57 blank | 119 comment | 17 complexity | f20a3f33d121d11d3bb79daafdbc793c MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, MPL-2.0-no-copyleft-exception
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2010 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Lachlan Roche |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id: md5.c 293036 2010-01-03 09:23:27Z sebastian $ */
  19. /*
  20. * md5.c - Copyright 1997 Lachlan Roche
  21. * md5_file() added by Alessandro Astarita <aleast@capri.it>
  22. */
  23. #include "php.h"
  24. #include "md5.h"
  25. PHPAPI void make_digest(char *md5str, unsigned char *digest)
  26. {
  27. make_digest_ex(md5str, digest, 16);
  28. }
  29. PHPAPI void make_digest_ex(char *md5str, unsigned char *digest, int len)
  30. {
  31. static const char hexits[17] = "0123456789abcdef";
  32. int i;
  33. for (i = 0; i < len; i++) {
  34. md5str[i * 2] = hexits[digest[i] >> 4];
  35. md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F];
  36. }
  37. md5str[len * 2] = '\0';
  38. }
  39. /* {{{ proto string md5(string str, [ bool raw_output])
  40. Calculate the md5 hash of a string */
  41. PHP_NAMED_FUNCTION(php_if_md5)
  42. {
  43. char *arg;
  44. int arg_len;
  45. zend_bool raw_output = 0;
  46. char md5str[33];
  47. PHP_MD5_CTX context;
  48. unsigned char digest[16];
  49. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
  50. return;
  51. }
  52. md5str[0] = '\0';
  53. PHP_MD5Init(&context);
  54. PHP_MD5Update(&context, arg, arg_len);
  55. PHP_MD5Final(digest, &context);
  56. if (raw_output) {
  57. RETURN_STRINGL(digest, 16, 1);
  58. } else {
  59. make_digest_ex(md5str, digest, 16);
  60. RETVAL_STRING(md5str, 1);
  61. }
  62. }
  63. /* }}} */
  64. /* {{{ proto string md5_file(string filename [, bool raw_output])
  65. Calculate the md5 hash of given filename */
  66. PHP_NAMED_FUNCTION(php_if_md5_file)
  67. {
  68. char *arg;
  69. int arg_len;
  70. zend_bool raw_output = 0;
  71. char md5str[33];
  72. unsigned char buf[1024];
  73. unsigned char digest[16];
  74. PHP_MD5_CTX context;
  75. int n;
  76. php_stream *stream;
  77. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
  78. return;
  79. }
  80. stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
  81. if (!stream) {
  82. RETURN_FALSE;
  83. }
  84. PHP_MD5Init(&context);
  85. while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
  86. PHP_MD5Update(&context, buf, n);
  87. }
  88. PHP_MD5Final(digest, &context);
  89. php_stream_close(stream);
  90. if (n<0) {
  91. RETURN_FALSE;
  92. }
  93. if (raw_output) {
  94. RETURN_STRINGL(digest, 16, 1);
  95. } else {
  96. make_digest_ex(md5str, digest, 16);
  97. RETVAL_STRING(md5str, 1);
  98. }
  99. }
  100. /* }}} */
  101. /*
  102. * The remaining code is the reference MD5 code (md5c.c) from rfc1321
  103. */
  104. /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
  105. */
  106. /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
  107. rights reserved.
  108. License to copy and use this software is granted provided that it
  109. is identified as the "RSA Data Security, Inc. MD5 Message-Digest
  110. Algorithm" in all material mentioning or referencing this software
  111. or this function.
  112. License is also granted to make and use derivative works provided
  113. that such works are identified as "derived from the RSA Data
  114. Security, Inc. MD5 Message-Digest Algorithm" in all material
  115. mentioning or referencing the derived work.
  116. RSA Data Security, Inc. makes no representations concerning either
  117. the merchantability of this software or the suitability of this
  118. software for any particular purpose. It is provided "as is"
  119. without express or implied warranty of any kind.
  120. These notices must be retained in any copies of any part of this
  121. documentation and/or software.
  122. */
  123. /* Constants for MD5Transform routine.
  124. */
  125. #define S11 7
  126. #define S12 12
  127. #define S13 17
  128. #define S14 22
  129. #define S21 5
  130. #define S22 9
  131. #define S23 14
  132. #define S24 20
  133. #define S31 4
  134. #define S32 11
  135. #define S33 16
  136. #define S34 23
  137. #define S41 6
  138. #define S42 10
  139. #define S43 15
  140. #define S44 21
  141. static void MD5Transform(php_uint32[4], const unsigned char[64]);
  142. static void Encode(unsigned char *, php_uint32 *, unsigned int);
  143. static void Decode(php_uint32 *, const unsigned char *, unsigned int);
  144. static unsigned char PADDING[64] =
  145. {
  146. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  147. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  148. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  149. };
  150. /* F, G, H and I are basic MD5 functions.
  151. */
  152. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  153. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  154. #define H(x, y, z) ((x) ^ (y) ^ (z))
  155. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  156. /* ROTATE_LEFT rotates x left n bits.
  157. */
  158. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  159. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  160. Rotation is separate from addition to prevent recomputation.
  161. */
  162. #define FF(a, b, c, d, x, s, ac) { \
  163. (a) += F ((b), (c), (d)) + (x) + (php_uint32)(ac); \
  164. (a) = ROTATE_LEFT ((a), (s)); \
  165. (a) += (b); \
  166. }
  167. #define GG(a, b, c, d, x, s, ac) { \
  168. (a) += G ((b), (c), (d)) + (x) + (php_uint32)(ac); \
  169. (a) = ROTATE_LEFT ((a), (s)); \
  170. (a) += (b); \
  171. }
  172. #define HH(a, b, c, d, x, s, ac) { \
  173. (a) += H ((b), (c), (d)) + (x) + (php_uint32)(ac); \
  174. (a) = ROTATE_LEFT ((a), (s)); \
  175. (a) += (b); \
  176. }
  177. #define II(a, b, c, d, x, s, ac) { \
  178. (a) += I ((b), (c), (d)) + (x) + (php_uint32)(ac); \
  179. (a) = ROTATE_LEFT ((a), (s)); \
  180. (a) += (b); \
  181. }
  182. /* {{{ PHP_MD5Init
  183. * MD5 initialization. Begins an MD5 operation, writing a new context.
  184. */
  185. PHPAPI void PHP_MD5Init(PHP_MD5_CTX * context)
  186. {
  187. context->count[0] = context->count[1] = 0;
  188. /* Load magic initialization constants.
  189. */
  190. context->state[0] = 0x67452301;
  191. context->state[1] = 0xefcdab89;
  192. context->state[2] = 0x98badcfe;
  193. context->state[3] = 0x10325476;
  194. }
  195. /* }}} */
  196. /* {{{ PHP_MD5Update
  197. MD5 block update operation. Continues an MD5 message-digest
  198. operation, processing another message block, and updating the
  199. context.
  200. */
  201. PHPAPI void PHP_MD5Update(PHP_MD5_CTX * context, const unsigned char *input,
  202. unsigned int inputLen)
  203. {
  204. unsigned int i, index, partLen;
  205. /* Compute number of bytes mod 64 */
  206. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  207. /* Update number of bits */
  208. if ((context->count[0] += ((php_uint32) inputLen << 3))
  209. < ((php_uint32) inputLen << 3))
  210. context->count[1]++;
  211. context->count[1] += ((php_uint32) inputLen >> 29);
  212. partLen = 64 - index;
  213. /* Transform as many times as possible.
  214. */
  215. if (inputLen >= partLen) {
  216. memcpy
  217. ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  218. MD5Transform(context->state, context->buffer);
  219. for (i = partLen; i + 63 < inputLen; i += 64)
  220. MD5Transform(context->state, &input[i]);
  221. index = 0;
  222. } else
  223. i = 0;
  224. /* Buffer remaining input */
  225. memcpy
  226. ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
  227. inputLen - i);
  228. }
  229. /* }}} */
  230. /* {{{ PHP_MD5Final
  231. MD5 finalization. Ends an MD5 message-digest operation, writing the
  232. the message digest and zeroizing the context.
  233. */
  234. PHPAPI void PHP_MD5Final(unsigned char digest[16], PHP_MD5_CTX * context)
  235. {
  236. unsigned char bits[8];
  237. unsigned int index, padLen;
  238. /* Save number of bits */
  239. Encode(bits, context->count, 8);
  240. /* Pad out to 56 mod 64.
  241. */
  242. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  243. padLen = (index < 56) ? (56 - index) : (120 - index);
  244. PHP_MD5Update(context, PADDING, padLen);
  245. /* Append length (before padding) */
  246. PHP_MD5Update(context, bits, 8);
  247. /* Store state in digest */
  248. Encode(digest, context->state, 16);
  249. /* Zeroize sensitive information.
  250. */
  251. memset((unsigned char*) context, 0, sizeof(*context));
  252. }
  253. /* }}} */
  254. /* {{{ MD5Transform
  255. * MD5 basic transformation. Transforms state based on block.
  256. */
  257. static void MD5Transform(state, block)
  258. php_uint32 state[4];
  259. const unsigned char block[64];
  260. {
  261. php_uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
  262. Decode(x, block, 64);
  263. /* Round 1 */
  264. FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
  265. FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
  266. FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
  267. FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
  268. FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
  269. FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
  270. FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
  271. FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
  272. FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
  273. FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
  274. FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  275. FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  276. FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  277. FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  278. FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  279. FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  280. /* Round 2 */
  281. GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
  282. GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
  283. GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  284. GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
  285. GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
  286. GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
  287. GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  288. GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
  289. GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
  290. GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  291. GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
  292. GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
  293. GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  294. GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
  295. GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
  296. GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  297. /* Round 3 */
  298. HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
  299. HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
  300. HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  301. HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  302. HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
  303. HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
  304. HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
  305. HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  306. HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  307. HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
  308. HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
  309. HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
  310. HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
  311. HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  312. HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  313. HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
  314. /* Round 4 */
  315. II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
  316. II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
  317. II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  318. II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
  319. II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  320. II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
  321. II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  322. II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
  323. II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
  324. II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  325. II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
  326. II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  327. II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
  328. II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  329. II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
  330. II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
  331. state[0] += a;
  332. state[1] += b;
  333. state[2] += c;
  334. state[3] += d;
  335. /* Zeroize sensitive information. */
  336. memset((unsigned char*) x, 0, sizeof(x));
  337. }
  338. /* }}} */
  339. /* {{{ Encode
  340. Encodes input (php_uint32) into output (unsigned char). Assumes len is
  341. a multiple of 4.
  342. */
  343. static void Encode(output, input, len)
  344. unsigned char *output;
  345. php_uint32 *input;
  346. unsigned int len;
  347. {
  348. unsigned int i, j;
  349. for (i = 0, j = 0; j < len; i++, j += 4) {
  350. output[j] = (unsigned char) (input[i] & 0xff);
  351. output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
  352. output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
  353. output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
  354. }
  355. }
  356. /* }}} */
  357. /* {{{ Decode
  358. Decodes input (unsigned char) into output (php_uint32). Assumes len is
  359. a multiple of 4.
  360. */
  361. static void Decode(output, input, len)
  362. php_uint32 *output;
  363. const unsigned char *input;
  364. unsigned int len;
  365. {
  366. unsigned int i, j;
  367. for (i = 0, j = 0; j < len; i++, j += 4)
  368. output[i] = ((php_uint32) input[j]) | (((php_uint32) input[j + 1]) << 8) |
  369. (((php_uint32) input[j + 2]) << 16) | (((php_uint32) input[j + 3]) << 24);
  370. }
  371. /* }}} */
  372. /*
  373. * Local variables:
  374. * tab-width: 4
  375. * c-basic-offset: 4
  376. * End:
  377. * vim600: sw=4 ts=4 fdm=marker
  378. * vim<600: sw=4 ts=4
  379. */