Coverage Report

Created: 2025-09-27 06:26

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