hash_ripemd.c 24 KB

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