PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/standard/sha1.c

http://github.com/infusion/PHP
C | 412 lines | 267 code | 56 blank | 89 comment | 16 complexity | 137a3676ee58c4c88a1a49b7e1c13a2c MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2011 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: Stefan Esser <sesser@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id: sha1.c 306939 2011-01-01 02:19:59Z felipe $ */
  19. #include "php.h"
  20. /* This code is heavily based on the PHP md5 implementation */
  21. #include "sha1.h"
  22. #include "md5.h"
  23. PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest)
  24. {
  25. make_digest_ex(sha1str, digest, 20);
  26. }
  27. /* {{{ proto string sha1(string str [, bool raw_output])
  28. Calculate the sha1 hash of a string */
  29. PHP_FUNCTION(sha1)
  30. {
  31. char *arg;
  32. int arg_len;
  33. zend_bool raw_output = 0;
  34. char sha1str[41];
  35. PHP_SHA1_CTX context;
  36. unsigned char digest[20];
  37. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
  38. return;
  39. }
  40. sha1str[0] = '\0';
  41. PHP_SHA1Init(&context);
  42. PHP_SHA1Update(&context, arg, arg_len);
  43. PHP_SHA1Final(digest, &context);
  44. if (raw_output) {
  45. RETURN_STRINGL(digest, 20, 1);
  46. } else {
  47. make_digest_ex(sha1str, digest, 20);
  48. RETVAL_STRING(sha1str, 1);
  49. }
  50. }
  51. /* }}} */
  52. /* {{{ proto string sha1_file(string filename [, bool raw_output])
  53. Calculate the sha1 hash of given filename */
  54. PHP_FUNCTION(sha1_file)
  55. {
  56. char *arg;
  57. int arg_len;
  58. zend_bool raw_output = 0;
  59. char sha1str[41];
  60. unsigned char buf[1024];
  61. unsigned char digest[20];
  62. PHP_SHA1_CTX context;
  63. int n;
  64. php_stream *stream;
  65. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
  66. return;
  67. }
  68. stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
  69. if (!stream) {
  70. RETURN_FALSE;
  71. }
  72. PHP_SHA1Init(&context);
  73. while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
  74. PHP_SHA1Update(&context, buf, n);
  75. }
  76. PHP_SHA1Final(digest, &context);
  77. php_stream_close(stream);
  78. if (n<0) {
  79. RETURN_FALSE;
  80. }
  81. if (raw_output) {
  82. RETURN_STRINGL(digest, 20, 1);
  83. } else {
  84. make_digest_ex(sha1str, digest, 20);
  85. RETVAL_STRING(sha1str, 1);
  86. }
  87. }
  88. /* }}} */
  89. static void SHA1Transform(php_uint32[5], const unsigned char[64]);
  90. static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
  91. static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);
  92. static unsigned char PADDING[64] =
  93. {
  94. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  95. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  96. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  97. };
  98. /* F, G, H and I are basic SHA1 functions.
  99. */
  100. #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
  101. #define G(x, y, z) ((x) ^ (y) ^ (z))
  102. #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
  103. #define I(x, y, z) ((x) ^ (y) ^ (z))
  104. /* ROTATE_LEFT rotates x left n bits.
  105. */
  106. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  107. /* W[i]
  108. */
  109. #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
  110. (x[i&15]=ROTATE_LEFT(tmp, 1)) )
  111. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  112. */
  113. #define FF(a, b, c, d, e, w) { \
  114. (e) += F ((b), (c), (d)) + (w) + (php_uint32)(0x5A827999); \
  115. (e) += ROTATE_LEFT ((a), 5); \
  116. (b) = ROTATE_LEFT((b), 30); \
  117. }
  118. #define GG(a, b, c, d, e, w) { \
  119. (e) += G ((b), (c), (d)) + (w) + (php_uint32)(0x6ED9EBA1); \
  120. (e) += ROTATE_LEFT ((a), 5); \
  121. (b) = ROTATE_LEFT((b), 30); \
  122. }
  123. #define HH(a, b, c, d, e, w) { \
  124. (e) += H ((b), (c), (d)) + (w) + (php_uint32)(0x8F1BBCDC); \
  125. (e) += ROTATE_LEFT ((a), 5); \
  126. (b) = ROTATE_LEFT((b), 30); \
  127. }
  128. #define II(a, b, c, d, e, w) { \
  129. (e) += I ((b), (c), (d)) + (w) + (php_uint32)(0xCA62C1D6); \
  130. (e) += ROTATE_LEFT ((a), 5); \
  131. (b) = ROTATE_LEFT((b), 30); \
  132. }
  133. /* {{{ PHP_SHA1Init
  134. * SHA1 initialization. Begins an SHA1 operation, writing a new context.
  135. */
  136. PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
  137. {
  138. context->count[0] = context->count[1] = 0;
  139. /* Load magic initialization constants.
  140. */
  141. context->state[0] = 0x67452301;
  142. context->state[1] = 0xefcdab89;
  143. context->state[2] = 0x98badcfe;
  144. context->state[3] = 0x10325476;
  145. context->state[4] = 0xc3d2e1f0;
  146. }
  147. /* }}} */
  148. /* {{{ PHP_SHA1Update
  149. SHA1 block update operation. Continues an SHA1 message-digest
  150. operation, processing another message block, and updating the
  151. context.
  152. */
  153. PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
  154. unsigned int inputLen)
  155. {
  156. unsigned int i, index, partLen;
  157. /* Compute number of bytes mod 64 */
  158. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  159. /* Update number of bits */
  160. if ((context->count[0] += ((php_uint32) inputLen << 3))
  161. < ((php_uint32) inputLen << 3))
  162. context->count[1]++;
  163. context->count[1] += ((php_uint32) inputLen >> 29);
  164. partLen = 64 - index;
  165. /* Transform as many times as possible.
  166. */
  167. if (inputLen >= partLen) {
  168. memcpy
  169. ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  170. SHA1Transform(context->state, context->buffer);
  171. for (i = partLen; i + 63 < inputLen; i += 64)
  172. SHA1Transform(context->state, &input[i]);
  173. index = 0;
  174. } else
  175. i = 0;
  176. /* Buffer remaining input */
  177. memcpy
  178. ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
  179. inputLen - i);
  180. }
  181. /* }}} */
  182. /* {{{ PHP_SHA1Final
  183. SHA1 finalization. Ends an SHA1 message-digest operation, writing the
  184. the message digest and zeroizing the context.
  185. */
  186. PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
  187. {
  188. unsigned char bits[8];
  189. unsigned int index, padLen;
  190. /* Save number of bits */
  191. bits[7] = context->count[0] & 0xFF;
  192. bits[6] = (context->count[0] >> 8) & 0xFF;
  193. bits[5] = (context->count[0] >> 16) & 0xFF;
  194. bits[4] = (context->count[0] >> 24) & 0xFF;
  195. bits[3] = context->count[1] & 0xFF;
  196. bits[2] = (context->count[1] >> 8) & 0xFF;
  197. bits[1] = (context->count[1] >> 16) & 0xFF;
  198. bits[0] = (context->count[1] >> 24) & 0xFF;
  199. /* Pad out to 56 mod 64.
  200. */
  201. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  202. padLen = (index < 56) ? (56 - index) : (120 - index);
  203. PHP_SHA1Update(context, PADDING, padLen);
  204. /* Append length (before padding) */
  205. PHP_SHA1Update(context, bits, 8);
  206. /* Store state in digest */
  207. SHA1Encode(digest, context->state, 20);
  208. /* Zeroize sensitive information.
  209. */
  210. memset((unsigned char*) context, 0, sizeof(*context));
  211. }
  212. /* }}} */
  213. /* {{{ SHA1Transform
  214. * SHA1 basic transformation. Transforms state based on block.
  215. */
  216. static void SHA1Transform(state, block)
  217. php_uint32 state[5];
  218. const unsigned char block[64];
  219. {
  220. php_uint32 a = state[0], b = state[1], c = state[2];
  221. php_uint32 d = state[3], e = state[4], x[16], tmp;
  222. SHA1Decode(x, block, 64);
  223. /* Round 1 */
  224. FF(a, b, c, d, e, x[0]); /* 1 */
  225. FF(e, a, b, c, d, x[1]); /* 2 */
  226. FF(d, e, a, b, c, x[2]); /* 3 */
  227. FF(c, d, e, a, b, x[3]); /* 4 */
  228. FF(b, c, d, e, a, x[4]); /* 5 */
  229. FF(a, b, c, d, e, x[5]); /* 6 */
  230. FF(e, a, b, c, d, x[6]); /* 7 */
  231. FF(d, e, a, b, c, x[7]); /* 8 */
  232. FF(c, d, e, a, b, x[8]); /* 9 */
  233. FF(b, c, d, e, a, x[9]); /* 10 */
  234. FF(a, b, c, d, e, x[10]); /* 11 */
  235. FF(e, a, b, c, d, x[11]); /* 12 */
  236. FF(d, e, a, b, c, x[12]); /* 13 */
  237. FF(c, d, e, a, b, x[13]); /* 14 */
  238. FF(b, c, d, e, a, x[14]); /* 15 */
  239. FF(a, b, c, d, e, x[15]); /* 16 */
  240. FF(e, a, b, c, d, W(16)); /* 17 */
  241. FF(d, e, a, b, c, W(17)); /* 18 */
  242. FF(c, d, e, a, b, W(18)); /* 19 */
  243. FF(b, c, d, e, a, W(19)); /* 20 */
  244. /* Round 2 */
  245. GG(a, b, c, d, e, W(20)); /* 21 */
  246. GG(e, a, b, c, d, W(21)); /* 22 */
  247. GG(d, e, a, b, c, W(22)); /* 23 */
  248. GG(c, d, e, a, b, W(23)); /* 24 */
  249. GG(b, c, d, e, a, W(24)); /* 25 */
  250. GG(a, b, c, d, e, W(25)); /* 26 */
  251. GG(e, a, b, c, d, W(26)); /* 27 */
  252. GG(d, e, a, b, c, W(27)); /* 28 */
  253. GG(c, d, e, a, b, W(28)); /* 29 */
  254. GG(b, c, d, e, a, W(29)); /* 30 */
  255. GG(a, b, c, d, e, W(30)); /* 31 */
  256. GG(e, a, b, c, d, W(31)); /* 32 */
  257. GG(d, e, a, b, c, W(32)); /* 33 */
  258. GG(c, d, e, a, b, W(33)); /* 34 */
  259. GG(b, c, d, e, a, W(34)); /* 35 */
  260. GG(a, b, c, d, e, W(35)); /* 36 */
  261. GG(e, a, b, c, d, W(36)); /* 37 */
  262. GG(d, e, a, b, c, W(37)); /* 38 */
  263. GG(c, d, e, a, b, W(38)); /* 39 */
  264. GG(b, c, d, e, a, W(39)); /* 40 */
  265. /* Round 3 */
  266. HH(a, b, c, d, e, W(40)); /* 41 */
  267. HH(e, a, b, c, d, W(41)); /* 42 */
  268. HH(d, e, a, b, c, W(42)); /* 43 */
  269. HH(c, d, e, a, b, W(43)); /* 44 */
  270. HH(b, c, d, e, a, W(44)); /* 45 */
  271. HH(a, b, c, d, e, W(45)); /* 46 */
  272. HH(e, a, b, c, d, W(46)); /* 47 */
  273. HH(d, e, a, b, c, W(47)); /* 48 */
  274. HH(c, d, e, a, b, W(48)); /* 49 */
  275. HH(b, c, d, e, a, W(49)); /* 50 */
  276. HH(a, b, c, d, e, W(50)); /* 51 */
  277. HH(e, a, b, c, d, W(51)); /* 52 */
  278. HH(d, e, a, b, c, W(52)); /* 53 */
  279. HH(c, d, e, a, b, W(53)); /* 54 */
  280. HH(b, c, d, e, a, W(54)); /* 55 */
  281. HH(a, b, c, d, e, W(55)); /* 56 */
  282. HH(e, a, b, c, d, W(56)); /* 57 */
  283. HH(d, e, a, b, c, W(57)); /* 58 */
  284. HH(c, d, e, a, b, W(58)); /* 59 */
  285. HH(b, c, d, e, a, W(59)); /* 60 */
  286. /* Round 4 */
  287. II(a, b, c, d, e, W(60)); /* 61 */
  288. II(e, a, b, c, d, W(61)); /* 62 */
  289. II(d, e, a, b, c, W(62)); /* 63 */
  290. II(c, d, e, a, b, W(63)); /* 64 */
  291. II(b, c, d, e, a, W(64)); /* 65 */
  292. II(a, b, c, d, e, W(65)); /* 66 */
  293. II(e, a, b, c, d, W(66)); /* 67 */
  294. II(d, e, a, b, c, W(67)); /* 68 */
  295. II(c, d, e, a, b, W(68)); /* 69 */
  296. II(b, c, d, e, a, W(69)); /* 70 */
  297. II(a, b, c, d, e, W(70)); /* 71 */
  298. II(e, a, b, c, d, W(71)); /* 72 */
  299. II(d, e, a, b, c, W(72)); /* 73 */
  300. II(c, d, e, a, b, W(73)); /* 74 */
  301. II(b, c, d, e, a, W(74)); /* 75 */
  302. II(a, b, c, d, e, W(75)); /* 76 */
  303. II(e, a, b, c, d, W(76)); /* 77 */
  304. II(d, e, a, b, c, W(77)); /* 78 */
  305. II(c, d, e, a, b, W(78)); /* 79 */
  306. II(b, c, d, e, a, W(79)); /* 80 */
  307. state[0] += a;
  308. state[1] += b;
  309. state[2] += c;
  310. state[3] += d;
  311. state[4] += e;
  312. /* Zeroize sensitive information. */
  313. memset((unsigned char*) x, 0, sizeof(x));
  314. }
  315. /* }}} */
  316. /* {{{ SHA1Encode
  317. Encodes input (php_uint32) into output (unsigned char). Assumes len is
  318. a multiple of 4.
  319. */
  320. static void SHA1Encode(output, input, len)
  321. unsigned char *output;
  322. php_uint32 *input;
  323. unsigned int len;
  324. {
  325. unsigned int i, j;
  326. for (i = 0, j = 0; j < len; i++, j += 4) {
  327. output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
  328. output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
  329. output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
  330. output[j + 3] = (unsigned char) (input[i] & 0xff);
  331. }
  332. }
  333. /* }}} */
  334. /* {{{ SHA1Decode
  335. Decodes input (unsigned char) into output (php_uint32). Assumes len is
  336. a multiple of 4.
  337. */
  338. static void SHA1Decode(output, input, len)
  339. php_uint32 *output;
  340. const unsigned char *input;
  341. unsigned int len;
  342. {
  343. unsigned int i, j;
  344. for (i = 0, j = 0; j < len; i++, j += 4)
  345. output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
  346. (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
  347. }
  348. /* }}} */
  349. /*
  350. * Local variables:
  351. * tab-width: 4
  352. * c-basic-offset: 4
  353. * End:
  354. * vim600: sw=4 ts=4 fdm=marker
  355. * vim<600: sw=4 ts=4
  356. */