Coverage Report

Created: 2026-02-14 06:52

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