Coverage Report

Created: 2025-06-13 06:43

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