hash_ripemd.c 24 KB

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