Coverage Report

Created: 2025-11-16 06:23

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
73
{
89
73
  context->count[0] = context->count[1] = 0;
90
  /* Load magic initialization constants.
91
   */
92
73
  context->state[0] = 0x67452301;
93
73
  context->state[1] = 0xEFCDAB89;
94
73
  context->state[2] = 0x98BADCFE;
95
73
  context->state[3] = 0x10325476;
96
73
}
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
80
{
104
80
  context->count[0] = context->count[1] = 0;
105
  /* Load magic initialization constants.
106
   */
107
80
  context->state[0] = 0x67452301;
108
80
  context->state[1] = 0xEFCDAB89;
109
80
  context->state[2] = 0x98BADCFE;
110
80
  context->state[3] = 0x10325476;
111
80
  context->state[4] = 0x76543210;
112
80
  context->state[5] = 0xFEDCBA98;
113
80
  context->state[6] = 0x89ABCDEF;
114
80
  context->state[7] = 0x01234567;
115
80
}
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
110
{
123
110
  context->count[0] = context->count[1] = 0;
124
  /* Load magic initialization constants.
125
   */
126
110
  context->state[0] = 0x67452301;
127
110
  context->state[1] = 0xEFCDAB89;
128
110
  context->state[2] = 0x98BADCFE;
129
110
  context->state[3] = 0x10325476;
130
110
  context->state[4] = 0xC3D2E1F0;
131
110
}
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
87
{
139
87
  context->count[0] = context->count[1] = 0;
140
  /* Load magic initialization constants.
141
   */
142
87
  context->state[0] = 0x67452301;
143
87
  context->state[1] = 0xEFCDAB89;
144
87
  context->state[2] = 0x98BADCFE;
145
87
  context->state[3] = 0x10325476;
146
87
  context->state[4] = 0xC3D2E1F0;
147
87
  context->state[5] = 0x76543210;
148
87
  context->state[6] = 0xFEDCBA98;
149
87
  context->state[7] = 0x89ABCDEF;
150
87
  context->state[8] = 0x01234567;
151
87
  context->state[9] = 0x3C2D1E0F;
152
87
}
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
16.2M
#define ROLS(j, x)  (((x) << S[j])  | ((x) >> (32 - S[j])))
199
16.2M
#define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
200
23.9M
#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
216k
{
208
216k
  unsigned int i, j;
209
210
3.68M
  for (i = 0, j = 0; j < len; i++, j += 4)
211
3.46M
    output[i] = ((uint32_t) input[j + 0]) | (((uint32_t) input[j + 1]) << 8) |
212
3.46M
      (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
213
216k
}
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
24.2k
{
221
24.2k
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3];
222
24.2k
  uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3];
223
24.2k
  uint32_t tmp, x[16];
224
24.2k
  int j;
225
226
24.2k
  RIPEMDDecode(x, block, 64);
227
228
412k
  for(j = 0; j < 16; j++) {
229
388k
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j));
230
388k
    a = d; d = c; c = b; b = tmp;
231
388k
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
232
388k
    aa = dd; dd = cc; cc = bb; bb = tmp;
233
388k
  }
234
235
412k
  for(j = 16; j < 32; j++) {
236
388k
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j));
237
388k
    a = d; d = c; c = b; b = tmp;
238
388k
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
239
388k
    aa = dd; dd = cc; cc = bb; bb = tmp;
240
388k
  }
241
242
412k
  for(j = 32; j < 48; j++) {
243
388k
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j));
244
388k
    a = d; d = c; c = b; b = tmp;
245
388k
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
246
388k
    aa = dd; dd = cc; cc = bb; bb = tmp;
247
388k
  }
248
249
412k
  for(j = 48; j < 64; j++) {
250
388k
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j));
251
388k
    a = d; d = c; c = b; b = tmp;
252
388k
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
253
388k
    aa = dd; dd = cc; cc = bb; bb = tmp;
254
388k
  }
255
256
24.2k
  tmp = state[1] + c + dd;
257
24.2k
  state[1] = state[2] + d + aa;
258
24.2k
  state[2] = state[3] + a + bb;
259
24.2k
  state[3] = state[0] + b + cc;
260
24.2k
  state[0] = tmp;
261
262
24.2k
  tmp = 0;
263
24.2k
  ZEND_SECURE_ZERO(x, sizeof(x));
264
24.2k
}
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
219
{
274
219
  unsigned int index, partLen;
275
219
  size_t i;
276
277
  /* Compute number of bytes mod 64 */
278
219
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
279
280
  /* Update number of bits */
281
219
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
282
8
    context->count[1]++;
283
8
  }
284
219
  context->count[1] += (uint32_t) (inputLen >> 29);
285
286
219
  partLen = 64 - index;
287
288
  /* Transform as many times as possible.
289
   */
290
219
  if (inputLen >= partLen) {
291
150
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
292
150
    RIPEMD128Transform(context->state, context->buffer);
293
294
24.2k
    for (i = partLen; i + 63 < inputLen; i += 64) {
295
24.1k
      RIPEMD128Transform(context->state, &input[i]);
296
24.1k
    }
297
298
150
    index = 0;
299
150
  } else {
300
69
    i = 0;
301
69
  }
302
303
  /* Buffer remaining input */
304
219
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
305
219
}
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
42.2k
{
313
42.2k
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3];
314
42.2k
  uint32_t aa = state[4], bb = state[5], cc = state[6], dd = state[7];
315
42.2k
  uint32_t tmp, x[16];
316
42.2k
  int j;
317
318
42.2k
  RIPEMDDecode(x, block, 64);
319
320
718k
  for(j = 0; j < 16; j++) {
321
676k
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j));
322
676k
    a = d; d = c; c = b; b = tmp;
323
676k
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
324
676k
    aa = dd; dd = cc; cc = bb; bb = tmp;
325
676k
  }
326
42.2k
  tmp = a; a = aa; aa = tmp;
327
328
718k
  for(j = 16; j < 32; j++) {
329
676k
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j));
330
676k
    a = d; d = c; c = b; b = tmp;
331
676k
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
332
676k
    aa = dd; dd = cc; cc = bb; bb = tmp;
333
676k
  }
334
42.2k
  tmp = b; b = bb; bb = tmp;
335
336
718k
  for(j = 32; j < 48; j++) {
337
676k
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j));
338
676k
    a = d; d = c; c = b; b = tmp;
339
676k
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
340
676k
    aa = dd; dd = cc; cc = bb; bb = tmp;
341
676k
  }
342
42.2k
  tmp = c; c = cc; cc = tmp;
343
344
718k
  for(j = 48; j < 64; j++) {
345
676k
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j));
346
676k
    a = d; d = c; c = b; b = tmp;
347
676k
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
348
676k
    aa = dd; dd = cc; cc = bb; bb = tmp;
349
676k
  }
350
42.2k
  tmp = d; d = dd; dd = tmp;
351
352
42.2k
  state[0] += a;
353
42.2k
  state[1] += b;
354
42.2k
  state[2] += c;
355
42.2k
  state[3] += d;
356
42.2k
  state[4] += aa;
357
42.2k
  state[5] += bb;
358
42.2k
  state[6] += cc;
359
42.2k
  state[7] += dd;
360
361
42.2k
  tmp = 0;
362
42.2k
  ZEND_SECURE_ZERO(x, sizeof(x));
363
42.2k
}
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
240
{
373
240
  unsigned int index, partLen;
374
240
  size_t i;
375
376
  /* Compute number of bytes mod 64 */
377
240
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
378
379
  /* Update number of bits */
380
240
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
381
36
    context->count[1]++;
382
36
  }
383
240
  context->count[1] += (uint32_t) (inputLen >> 29);
384
385
240
  partLen = 64 - index;
386
387
  /* Transform as many times as possible.
388
   */
389
240
  if (inputLen >= partLen) {
390
163
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
391
163
    RIPEMD256Transform(context->state, context->buffer);
392
393
42.2k
    for (i = partLen; i + 63 < inputLen; i += 64) {
394
42.0k
      RIPEMD256Transform(context->state, &input[i]);
395
42.0k
    }
396
397
163
    index = 0;
398
163
  } else {
399
77
    i = 0;
400
77
  }
401
402
  /* Buffer remaining input */
403
240
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
404
240
}
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
68.7k
{
412
68.7k
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3], e  = state[4];
413
68.7k
  uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
414
68.7k
  uint32_t tmp, x[16];
415
68.7k
  int j;
416
417
68.7k
  RIPEMDDecode(x, block, 64);
418
419
1.16M
  for(j = 0; j < 16; j++) {
420
1.10M
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j)) + e;
421
1.10M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
422
1.10M
    tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
423
1.10M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
424
1.10M
  }
425
426
1.16M
  for(j = 16; j < 32; j++) {
427
1.10M
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j)) + e;
428
1.10M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
429
1.10M
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
430
1.10M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
431
1.10M
  }
432
433
1.16M
  for(j = 32; j < 48; j++) {
434
1.10M
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j)) + e;
435
1.10M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
436
1.10M
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
437
1.10M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
438
1.10M
  }
439
440
1.16M
  for(j = 48; j < 64; j++) {
441
1.10M
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j)) + e;
442
1.10M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
443
1.10M
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
444
1.10M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
445
1.10M
  }
446
447
1.16M
  for(j = 64; j < 80; j++) {
448
1.10M
    tmp = ROLS( j, a  + F4(b,  c,  d)  + x[R[j]]  + K(j)) + e;
449
1.10M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
450
1.10M
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
451
1.10M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
452
1.10M
  }
453
454
68.7k
  tmp = state[1] + c + dd;
455
68.7k
  state[1] = state[2] + d + ee;
456
68.7k
  state[2] = state[3] + e + aa;
457
68.7k
  state[3] = state[4] + a + bb;
458
68.7k
  state[4] = state[0] + b + cc;
459
68.7k
  state[0] = tmp;
460
461
68.7k
  tmp = 0;
462
68.7k
  ZEND_SECURE_ZERO(x, sizeof(x));
463
68.7k
}
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
243
{
473
243
  unsigned int index, partLen;
474
243
  size_t i;
475
476
  /* Compute number of bytes mod 64 */
477
243
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
478
479
  /* Update number of bits */
480
243
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
481
38
    context->count[1]++;
482
38
  }
483
243
  context->count[1] += (uint32_t) (inputLen >> 29);
484
485
243
  partLen = 64 - index;
486
487
  /* Transform as many times as possible.
488
   */
489
243
  if (inputLen >= partLen) {
490
168
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
491
168
    RIPEMD160Transform(context->state, context->buffer);
492
493
68.7k
    for (i = partLen; i + 63 < inputLen; i += 64) {
494
68.6k
      RIPEMD160Transform(context->state, &input[i]);
495
68.6k
    }
496
497
168
    index = 0;
498
168
  } else {
499
75
    i = 0;
500
75
  }
501
502
  /* Buffer remaining input */
503
243
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
504
243
}
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
81.1k
{
512
81.1k
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3], e  = state[4];
513
81.1k
  uint32_t aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
514
81.1k
  uint32_t tmp, x[16];
515
81.1k
  int j;
516
517
81.1k
  RIPEMDDecode(x, block, 64);
518
519
1.38M
  for(j = 0; j < 16; j++) {
520
1.29M
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j)) + e;
521
1.29M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
522
1.29M
    tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
523
1.29M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
524
1.29M
  }
525
81.1k
  tmp = b; b = bb; bb = tmp;
526
527
1.38M
  for(j = 16; j < 32; j++) {
528
1.29M
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j)) + e;
529
1.29M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
530
1.29M
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
531
1.29M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
532
1.29M
  }
533
81.1k
  tmp = d; d = dd; dd = tmp;
534
535
1.38M
  for(j = 32; j < 48; j++) {
536
1.29M
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j)) + e;
537
1.29M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
538
1.29M
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
539
1.29M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
540
1.29M
  }
541
81.1k
  tmp = a; a = aa; aa = tmp;
542
543
1.38M
  for(j = 48; j < 64; j++) {
544
1.29M
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j)) + e;
545
1.29M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
546
1.29M
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
547
1.29M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
548
1.29M
  }
549
81.1k
  tmp = c; c = cc; cc = tmp;
550
551
1.38M
  for(j = 64; j < 80; j++) {
552
1.29M
    tmp = ROLS( j, a  + F4(b,  c,  d)  + x[R[j]]  + K(j)) + e;
553
1.29M
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
554
1.29M
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
555
1.29M
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
556
1.29M
  }
557
81.1k
  tmp = e; e = ee; ee = tmp;
558
559
81.1k
  state[0] += a;
560
81.1k
  state[1] += b;
561
81.1k
  state[2] += c;
562
81.1k
  state[3] += d;
563
81.1k
  state[4] += e;
564
81.1k
  state[5] += aa;
565
81.1k
  state[6] += bb;
566
81.1k
  state[7] += cc;
567
81.1k
  state[8] += dd;
568
81.1k
  state[9] += ee;
569
570
81.1k
  tmp = 0;
571
81.1k
  ZEND_SECURE_ZERO(x, sizeof(x));
572
81.1k
}
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
258
{
582
258
  unsigned int index, partLen;
583
258
  size_t i;
584
585
  /* Compute number of bytes mod 64 */
586
258
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
587
588
  /* Update number of bits */
589
258
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
590
42
    context->count[1]++;
591
42
  }
592
258
  context->count[1] += (uint32_t) (inputLen >> 29);
593
594
258
  partLen = 64 - index;
595
596
  /* Transform as many times as possible.
597
   */
598
258
  if (inputLen >= partLen) {
599
181
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
600
181
    RIPEMD320Transform(context->state, context->buffer);
601
602
81.1k
    for (i = partLen; i + 63 < inputLen; i += 64) {
603
81.0k
      RIPEMD320Transform(context->state, &input[i]);
604
81.0k
    }
605
606
181
    index = 0;
607
181
  } else {
608
77
    i = 0;
609
77
  }
610
611
  /* Buffer remaining input */
612
258
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
613
258
}
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
320
{
629
320
  unsigned int i, j;
630
631
2.51k
  for (i = 0, j = 0; j < len; i++, j += 4) {
632
2.19k
    output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
633
2.19k
    output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
634
2.19k
    output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
635
2.19k
    output[j + 0] = (unsigned char) (input[i] & 0xff);
636
2.19k
  }
637
320
}
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
73
{
646
73
  unsigned char bits[8];
647
73
  unsigned int index, padLen;
648
649
  /* Save number of bits */
650
73
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
651
73
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
652
73
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
653
73
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
654
73
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
655
73
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
656
73
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
657
73
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
658
659
  /* Pad out to 56 mod 64.
660
   */
661
73
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
662
73
  padLen = (index < 56) ? (56 - index) : (120 - index);
663
73
  PHP_RIPEMD128Update(context, PADDING, padLen);
664
665
  /* Append length (before padding) */
666
73
  PHP_RIPEMD128Update(context, bits, 8);
667
668
  /* Store state in digest */
669
73
  RIPEMDEncode(digest, context->state, 16);
670
671
  /* Zeroize sensitive information.
672
   */
673
73
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
674
73
}
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
80
{
683
80
  unsigned char bits[8];
684
80
  unsigned int index, padLen;
685
686
  /* Save number of bits */
687
80
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
688
80
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
689
80
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
690
80
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
691
80
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
692
80
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
693
80
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
694
80
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
695
696
  /* Pad out to 56 mod 64.
697
   */
698
80
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
699
80
  padLen = (index < 56) ? (56 - index) : (120 - index);
700
80
  PHP_RIPEMD256Update(context, PADDING, padLen);
701
702
  /* Append length (before padding) */
703
80
  PHP_RIPEMD256Update(context, bits, 8);
704
705
  /* Store state in digest */
706
80
  RIPEMDEncode(digest, context->state, 32);
707
708
  /* Zeroize sensitive information.
709
   */
710
80
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
711
80
}
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
81
{
720
81
  unsigned char bits[8];
721
81
  unsigned int index, padLen;
722
723
  /* Save number of bits */
724
81
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
725
81
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
726
81
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
727
81
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
728
81
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
729
81
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
730
81
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
731
81
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
732
733
  /* Pad out to 56 mod 64.
734
   */
735
81
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
736
81
  padLen = (index < 56) ? (56 - index) : (120 - index);
737
81
  PHP_RIPEMD160Update(context, PADDING, padLen);
738
739
  /* Append length (before padding) */
740
81
  PHP_RIPEMD160Update(context, bits, 8);
741
742
  /* Store state in digest */
743
81
  RIPEMDEncode(digest, context->state, 20);
744
745
  /* Zeroize sensitive information.
746
   */
747
81
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
748
81
}
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
86
{
757
86
  unsigned char bits[8];
758
86
  unsigned int index, padLen;
759
760
  /* Save number of bits */
761
86
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
762
86
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
763
86
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
764
86
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
765
86
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
766
86
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
767
86
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
768
86
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
769
770
  /* Pad out to 56 mod 64.
771
   */
772
86
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
773
86
  padLen = (index < 56) ? (56 - index) : (120 - index);
774
86
  PHP_RIPEMD320Update(context, PADDING, padLen);
775
776
  /* Append length (before padding) */
777
86
  PHP_RIPEMD320Update(context, bits, 8);
778
779
  /* Store state in digest */
780
86
  RIPEMDEncode(digest, context->state, 40);
781
782
  /* Zeroize sensitive information.
783
   */
784
86
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
785
86
}
786
/* }}} */