Coverage Report

Created: 2026-01-18 06:47

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