Coverage Report

Created: 2026-04-01 06:49

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