Coverage Report

Created: 2026-10-28 06:20

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