Coverage Report

Created: 2026-06-02 06:37

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