Coverage Report

Created: 2026-06-13 07:01

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