PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/hash/hash_ripemd.c

http://github.com/php/php-src
C | 766 lines | 492 code | 113 blank | 161 comment | 36 complexity | ed5c760c46f8d6a9e96168a3a920ee38 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | http://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Author: Sara Golemon <pollita@php.net> |
  14. +----------------------------------------------------------------------+
  15. */
  16. /* Heavily borrowed from md5.c & sha1.c of PHP archival fame
  17. Note that ripemd laughs in the face of logic and uses
  18. little endian byte ordering */
  19. #include "php_hash.h"
  20. #include "php_hash_ripemd.h"
  21. const php_hash_ops php_hash_ripemd128_ops = {
  22. (php_hash_init_func_t) PHP_RIPEMD128Init,
  23. (php_hash_update_func_t) PHP_RIPEMD128Update,
  24. (php_hash_final_func_t) PHP_RIPEMD128Final,
  25. (php_hash_copy_func_t) php_hash_copy,
  26. 16,
  27. 64,
  28. sizeof(PHP_RIPEMD128_CTX),
  29. 1
  30. };
  31. const php_hash_ops php_hash_ripemd160_ops = {
  32. (php_hash_init_func_t) PHP_RIPEMD160Init,
  33. (php_hash_update_func_t) PHP_RIPEMD160Update,
  34. (php_hash_final_func_t) PHP_RIPEMD160Final,
  35. (php_hash_copy_func_t) php_hash_copy,
  36. 20,
  37. 64,
  38. sizeof(PHP_RIPEMD160_CTX),
  39. 1
  40. };
  41. const php_hash_ops php_hash_ripemd256_ops = {
  42. (php_hash_init_func_t) PHP_RIPEMD256Init,
  43. (php_hash_update_func_t) PHP_RIPEMD256Update,
  44. (php_hash_final_func_t) PHP_RIPEMD256Final,
  45. (php_hash_copy_func_t) php_hash_copy,
  46. 32,
  47. 64,
  48. sizeof(PHP_RIPEMD256_CTX),
  49. 1
  50. };
  51. const php_hash_ops php_hash_ripemd320_ops = {
  52. (php_hash_init_func_t) PHP_RIPEMD320Init,
  53. (php_hash_update_func_t) PHP_RIPEMD320Update,
  54. (php_hash_final_func_t) PHP_RIPEMD320Final,
  55. (php_hash_copy_func_t) php_hash_copy,
  56. 40,
  57. 64,
  58. sizeof(PHP_RIPEMD320_CTX),
  59. 1
  60. };
  61. /* {{{ PHP_RIPEMD128Init
  62. * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
  63. */
  64. PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
  65. {
  66. context->count[0] = context->count[1] = 0;
  67. /* Load magic initialization constants.
  68. */
  69. context->state[0] = 0x67452301;
  70. context->state[1] = 0xEFCDAB89;
  71. context->state[2] = 0x98BADCFE;
  72. context->state[3] = 0x10325476;
  73. }
  74. /* }}} */
  75. /* {{{ PHP_RIPEMD256Init
  76. * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
  77. */
  78. PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
  79. {
  80. context->count[0] = context->count[1] = 0;
  81. /* Load magic initialization constants.
  82. */
  83. context->state[0] = 0x67452301;
  84. context->state[1] = 0xEFCDAB89;
  85. context->state[2] = 0x98BADCFE;
  86. context->state[3] = 0x10325476;
  87. context->state[4] = 0x76543210;
  88. context->state[5] = 0xFEDCBA98;
  89. context->state[6] = 0x89ABCDEF;
  90. context->state[7] = 0x01234567;
  91. }
  92. /* }}} */
  93. /* {{{ PHP_RIPEMD160Init
  94. * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
  95. */
  96. PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
  97. {
  98. context->count[0] = context->count[1] = 0;
  99. /* Load magic initialization constants.
  100. */
  101. context->state[0] = 0x67452301;
  102. context->state[1] = 0xEFCDAB89;
  103. context->state[2] = 0x98BADCFE;
  104. context->state[3] = 0x10325476;
  105. context->state[4] = 0xC3D2E1F0;
  106. }
  107. /* }}} */
  108. /* {{{ PHP_RIPEMD320Init
  109. * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
  110. */
  111. PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
  112. {
  113. context->count[0] = context->count[1] = 0;
  114. /* Load magic initialization constants.
  115. */
  116. context->state[0] = 0x67452301;
  117. context->state[1] = 0xEFCDAB89;
  118. context->state[2] = 0x98BADCFE;
  119. context->state[3] = 0x10325476;
  120. context->state[4] = 0xC3D2E1F0;
  121. context->state[5] = 0x76543210;
  122. context->state[6] = 0xFEDCBA98;
  123. context->state[7] = 0x89ABCDEF;
  124. context->state[8] = 0x01234567;
  125. context->state[9] = 0x3C2D1E0F;
  126. }
  127. /* }}} */
  128. /* Basic ripemd function */
  129. #define F0(x,y,z) ((x) ^ (y) ^ (z))
  130. #define F1(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
  131. #define F2(x,y,z) (((x) | (~(y))) ^ (z))
  132. #define F3(x,y,z) (((x) & (z)) | ((y) & (~(z))))
  133. #define F4(x,y,z) ((x) ^ ((y) | (~(z))))
  134. static const uint32_t K_values[5] = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E }; /* 128, 256, 160, 320 */
  135. static const uint32_t KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 }; /* 128 & 256 */
  136. static const uint32_t KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
  137. #define K(n) K_values[ (n) >> 4]
  138. #define KK(n) KK_values[(n) >> 4]
  139. #define KK160(n) KK160_values[(n) >> 4]
  140. static const unsigned char R[80] = {
  141. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  142. 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
  143. 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
  144. 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
  145. 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
  146. static const unsigned char RR[80] = {
  147. 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
  148. 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
  149. 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
  150. 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
  151. 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
  152. static const unsigned char S[80] = {
  153. 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
  154. 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
  155. 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
  156. 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
  157. 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
  158. static const unsigned char SS[80] = {
  159. 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
  160. 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
  161. 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
  162. 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
  163. 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
  164. #define ROLS(j, x) (((x) << S[j]) | ((x) >> (32 - S[j])))
  165. #define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
  166. #define ROL(n, x) (((x) << n) | ((x) >> (32 - n)))
  167. /* {{{ RIPEMDDecode
  168. Decodes input (unsigned char) into output (uint32_t). Assumes len is
  169. a multiple of 4.
  170. */
  171. static void RIPEMDDecode(uint32_t *output, const unsigned char *input, unsigned int len)
  172. {
  173. unsigned int i, j;
  174. for (i = 0, j = 0; j < len; i++, j += 4)
  175. output[i] = ((uint32_t) input[j + 0]) | (((uint32_t) input[j + 1]) << 8) |
  176. (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
  177. }
  178. /* }}} */
  179. /* {{{ RIPEMD128Transform
  180. * ripemd128 basic transformation. Transforms state based on block.
  181. */
  182. static void RIPEMD128Transform(uint32_t state[4], const unsigned char block[64])
  183. {
  184. uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
  185. uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3];
  186. uint32_t tmp, x[16];
  187. int j;
  188. RIPEMDDecode(x, block, 64);
  189. for(j = 0; j < 16; j++) {
  190. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
  191. a = d; d = c; c = b; b = tmp;
  192. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
  193. aa = dd; dd = cc; cc = bb; bb = tmp;
  194. }
  195. for(j = 16; j < 32; j++) {
  196. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
  197. a = d; d = c; c = b; b = tmp;
  198. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
  199. aa = dd; dd = cc; cc = bb; bb = tmp;
  200. }
  201. for(j = 32; j < 48; j++) {
  202. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
  203. a = d; d = c; c = b; b = tmp;
  204. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
  205. aa = dd; dd = cc; cc = bb; bb = tmp;
  206. }
  207. for(j = 48; j < 64; j++) {
  208. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
  209. a = d; d = c; c = b; b = tmp;
  210. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
  211. aa = dd; dd = cc; cc = bb; bb = tmp;
  212. }
  213. tmp = state[1] + c + dd;
  214. state[1] = state[2] + d + aa;
  215. state[2] = state[3] + a + bb;
  216. state[3] = state[0] + b + cc;
  217. state[0] = tmp;
  218. tmp = 0;
  219. ZEND_SECURE_ZERO(x, sizeof(x));
  220. }
  221. /* }}} */
  222. /* {{{ PHP_RIPEMD128Update
  223. ripemd128 block update operation. Continues a ripemd128 message-digest
  224. operation, processing another message block, and updating the
  225. context.
  226. */
  227. PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, size_t inputLen)
  228. {
  229. unsigned int i, index, partLen;
  230. /* Compute number of bytes mod 64 */
  231. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  232. /* Update number of bits */
  233. if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
  234. context->count[1]++;
  235. }
  236. context->count[1] += ((uint32_t) inputLen >> 29);
  237. partLen = 64 - index;
  238. /* Transform as many times as possible.
  239. */
  240. if (inputLen >= partLen) {
  241. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  242. RIPEMD128Transform(context->state, context->buffer);
  243. for (i = partLen; i + 63 < inputLen; i += 64) {
  244. RIPEMD128Transform(context->state, &input[i]);
  245. }
  246. index = 0;
  247. } else {
  248. i = 0;
  249. }
  250. /* Buffer remaining input */
  251. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  252. }
  253. /* }}} */
  254. /* {{{ RIPEMD256Transform
  255. * ripemd256 basic transformation. Transforms state based on block.
  256. */
  257. static void RIPEMD256Transform(uint32_t state[8], const unsigned char block[64])
  258. {
  259. uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
  260. uint32_t aa = state[4], bb = state[5], cc = state[6], dd = state[7];
  261. uint32_t tmp, x[16];
  262. int j;
  263. RIPEMDDecode(x, block, 64);
  264. for(j = 0; j < 16; j++) {
  265. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
  266. a = d; d = c; c = b; b = tmp;
  267. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
  268. aa = dd; dd = cc; cc = bb; bb = tmp;
  269. }
  270. tmp = a; a = aa; aa = tmp;
  271. for(j = 16; j < 32; j++) {
  272. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
  273. a = d; d = c; c = b; b = tmp;
  274. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
  275. aa = dd; dd = cc; cc = bb; bb = tmp;
  276. }
  277. tmp = b; b = bb; bb = tmp;
  278. for(j = 32; j < 48; j++) {
  279. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
  280. a = d; d = c; c = b; b = tmp;
  281. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
  282. aa = dd; dd = cc; cc = bb; bb = tmp;
  283. }
  284. tmp = c; c = cc; cc = tmp;
  285. for(j = 48; j < 64; j++) {
  286. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
  287. a = d; d = c; c = b; b = tmp;
  288. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
  289. aa = dd; dd = cc; cc = bb; bb = tmp;
  290. }
  291. tmp = d; d = dd; dd = tmp;
  292. state[0] += a;
  293. state[1] += b;
  294. state[2] += c;
  295. state[3] += d;
  296. state[4] += aa;
  297. state[5] += bb;
  298. state[6] += cc;
  299. state[7] += dd;
  300. tmp = 0;
  301. ZEND_SECURE_ZERO(x, sizeof(x));
  302. }
  303. /* }}} */
  304. /* {{{ PHP_RIPEMD256Update
  305. ripemd256 block update operation. Continues a ripemd256 message-digest
  306. operation, processing another message block, and updating the
  307. context.
  308. */
  309. PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, size_t inputLen)
  310. {
  311. unsigned int i, index, partLen;
  312. /* Compute number of bytes mod 64 */
  313. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  314. /* Update number of bits */
  315. if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
  316. context->count[1]++;
  317. }
  318. context->count[1] += ((uint32_t) inputLen >> 29);
  319. partLen = 64 - index;
  320. /* Transform as many times as possible.
  321. */
  322. if (inputLen >= partLen) {
  323. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  324. RIPEMD256Transform(context->state, context->buffer);
  325. for (i = partLen; i + 63 < inputLen; i += 64) {
  326. RIPEMD256Transform(context->state, &input[i]);
  327. }
  328. index = 0;
  329. } else {
  330. i = 0;
  331. }
  332. /* Buffer remaining input */
  333. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  334. }
  335. /* }}} */
  336. /* {{{ RIPEMD160Transform
  337. * ripemd160 basic transformation. Transforms state based on block.
  338. */
  339. static void RIPEMD160Transform(uint32_t state[5], const unsigned char block[64])
  340. {
  341. uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
  342. uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
  343. uint32_t tmp, x[16];
  344. int j;
  345. RIPEMDDecode(x, block, 64);
  346. for(j = 0; j < 16; j++) {
  347. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
  348. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  349. tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  350. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  351. }
  352. for(j = 16; j < 32; j++) {
  353. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
  354. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  355. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  356. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  357. }
  358. for(j = 32; j < 48; j++) {
  359. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
  360. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  361. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  362. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  363. }
  364. for(j = 48; j < 64; j++) {
  365. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
  366. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  367. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  368. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  369. }
  370. for(j = 64; j < 80; j++) {
  371. tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
  372. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  373. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  374. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  375. }
  376. tmp = state[1] + c + dd;
  377. state[1] = state[2] + d + ee;
  378. state[2] = state[3] + e + aa;
  379. state[3] = state[4] + a + bb;
  380. state[4] = state[0] + b + cc;
  381. state[0] = tmp;
  382. tmp = 0;
  383. ZEND_SECURE_ZERO(x, sizeof(x));
  384. }
  385. /* }}} */
  386. /* {{{ PHP_RIPEMD160Update
  387. ripemd160 block update operation. Continues a ripemd160 message-digest
  388. operation, processing another message block, and updating the
  389. context.
  390. */
  391. PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, size_t inputLen)
  392. {
  393. unsigned int i, index, partLen;
  394. /* Compute number of bytes mod 64 */
  395. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  396. /* Update number of bits */
  397. if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
  398. context->count[1]++;
  399. }
  400. context->count[1] += ((uint32_t) inputLen >> 29);
  401. partLen = 64 - index;
  402. /* Transform as many times as possible.
  403. */
  404. if (inputLen >= partLen) {
  405. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  406. RIPEMD160Transform(context->state, context->buffer);
  407. for (i = partLen; i + 63 < inputLen; i += 64) {
  408. RIPEMD160Transform(context->state, &input[i]);
  409. }
  410. index = 0;
  411. } else {
  412. i = 0;
  413. }
  414. /* Buffer remaining input */
  415. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  416. }
  417. /* }}} */
  418. /* {{{ RIPEMD320Transform
  419. * ripemd320 basic transformation. Transforms state based on block.
  420. */
  421. static void RIPEMD320Transform(uint32_t state[10], const unsigned char block[64])
  422. {
  423. uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
  424. uint32_t aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
  425. uint32_t tmp, x[16];
  426. int j;
  427. RIPEMDDecode(x, block, 64);
  428. for(j = 0; j < 16; j++) {
  429. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
  430. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  431. tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  432. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  433. }
  434. tmp = b; b = bb; bb = tmp;
  435. for(j = 16; j < 32; j++) {
  436. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
  437. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  438. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  439. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  440. }
  441. tmp = d; d = dd; dd = tmp;
  442. for(j = 32; j < 48; j++) {
  443. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
  444. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  445. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  446. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  447. }
  448. tmp = a; a = aa; aa = tmp;
  449. for(j = 48; j < 64; j++) {
  450. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
  451. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  452. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  453. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  454. }
  455. tmp = c; c = cc; cc = tmp;
  456. for(j = 64; j < 80; j++) {
  457. tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
  458. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  459. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  460. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  461. }
  462. tmp = e; e = ee; ee = tmp;
  463. state[0] += a;
  464. state[1] += b;
  465. state[2] += c;
  466. state[3] += d;
  467. state[4] += e;
  468. state[5] += aa;
  469. state[6] += bb;
  470. state[7] += cc;
  471. state[8] += dd;
  472. state[9] += ee;
  473. tmp = 0;
  474. ZEND_SECURE_ZERO(x, sizeof(x));
  475. }
  476. /* }}} */
  477. /* {{{ PHP_RIPEMD320Update
  478. ripemd320 block update operation. Continues a ripemd320 message-digest
  479. operation, processing another message block, and updating the
  480. context.
  481. */
  482. PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, size_t inputLen)
  483. {
  484. unsigned int i, index, partLen;
  485. /* Compute number of bytes mod 64 */
  486. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  487. /* Update number of bits */
  488. if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
  489. context->count[1]++;
  490. }
  491. context->count[1] += ((uint32_t) inputLen >> 29);
  492. partLen = 64 - index;
  493. /* Transform as many times as possible.
  494. */
  495. if (inputLen >= partLen) {
  496. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  497. RIPEMD320Transform(context->state, context->buffer);
  498. for (i = partLen; i + 63 < inputLen; i += 64) {
  499. RIPEMD320Transform(context->state, &input[i]);
  500. }
  501. index = 0;
  502. } else {
  503. i = 0;
  504. }
  505. /* Buffer remaining input */
  506. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  507. }
  508. /* }}} */
  509. static const unsigned char PADDING[64] =
  510. {
  511. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  512. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  513. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  514. };
  515. /* {{{ RIPEMDEncode
  516. Encodes input (uint32_t) into output (unsigned char). Assumes len is
  517. a multiple of 4.
  518. */
  519. static void RIPEMDEncode(unsigned char *output, uint32_t *input, unsigned int len)
  520. {
  521. unsigned int i, j;
  522. for (i = 0, j = 0; j < len; i++, j += 4) {
  523. output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
  524. output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
  525. output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
  526. output[j + 0] = (unsigned char) (input[i] & 0xff);
  527. }
  528. }
  529. /* }}} */
  530. /* {{{ PHP_RIPEMD128Final
  531. ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
  532. the message digest and zeroizing the context.
  533. */
  534. PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
  535. {
  536. unsigned char bits[8];
  537. unsigned int index, padLen;
  538. /* Save number of bits */
  539. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  540. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  541. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  542. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  543. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  544. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  545. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  546. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  547. /* Pad out to 56 mod 64.
  548. */
  549. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  550. padLen = (index < 56) ? (56 - index) : (120 - index);
  551. PHP_RIPEMD128Update(context, PADDING, padLen);
  552. /* Append length (before padding) */
  553. PHP_RIPEMD128Update(context, bits, 8);
  554. /* Store state in digest */
  555. RIPEMDEncode(digest, context->state, 16);
  556. /* Zeroize sensitive information.
  557. */
  558. ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
  559. }
  560. /* }}} */
  561. /* {{{ PHP_RIPEMD256Final
  562. ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
  563. the message digest and zeroizing the context.
  564. */
  565. PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
  566. {
  567. unsigned char bits[8];
  568. unsigned int index, padLen;
  569. /* Save number of bits */
  570. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  571. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  572. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  573. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  574. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  575. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  576. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  577. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  578. /* Pad out to 56 mod 64.
  579. */
  580. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  581. padLen = (index < 56) ? (56 - index) : (120 - index);
  582. PHP_RIPEMD256Update(context, PADDING, padLen);
  583. /* Append length (before padding) */
  584. PHP_RIPEMD256Update(context, bits, 8);
  585. /* Store state in digest */
  586. RIPEMDEncode(digest, context->state, 32);
  587. /* Zeroize sensitive information.
  588. */
  589. ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
  590. }
  591. /* }}} */
  592. /* {{{ PHP_RIPEMD160Final
  593. ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
  594. the message digest and zeroizing the context.
  595. */
  596. PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
  597. {
  598. unsigned char bits[8];
  599. unsigned int index, padLen;
  600. /* Save number of bits */
  601. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  602. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  603. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  604. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  605. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  606. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  607. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  608. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  609. /* Pad out to 56 mod 64.
  610. */
  611. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  612. padLen = (index < 56) ? (56 - index) : (120 - index);
  613. PHP_RIPEMD160Update(context, PADDING, padLen);
  614. /* Append length (before padding) */
  615. PHP_RIPEMD160Update(context, bits, 8);
  616. /* Store state in digest */
  617. RIPEMDEncode(digest, context->state, 20);
  618. /* Zeroize sensitive information.
  619. */
  620. ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
  621. }
  622. /* }}} */
  623. /* {{{ PHP_RIPEMD320Final
  624. ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
  625. the message digest and zeroizing the context.
  626. */
  627. PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
  628. {
  629. unsigned char bits[8];
  630. unsigned int index, padLen;
  631. /* Save number of bits */
  632. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  633. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  634. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  635. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  636. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  637. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  638. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  639. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  640. /* Pad out to 56 mod 64.
  641. */
  642. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  643. padLen = (index < 56) ? (56 - index) : (120 - index);
  644. PHP_RIPEMD320Update(context, PADDING, padLen);
  645. /* Append length (before padding) */
  646. PHP_RIPEMD320Update(context, bits, 8);
  647. /* Store state in digest */
  648. RIPEMDEncode(digest, context->state, 40);
  649. /* Zeroize sensitive information.
  650. */
  651. ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
  652. }
  653. /* }}} */