Coverage Report

Created: 2025-07-23 06:33

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