Coverage Report

Created: 2025-12-14 06:06

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