Coverage Report

Created: 2025-12-14 06:06

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