Coverage Report

Created: 2026-09-14 06:25

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