Coverage Report

Created: 2026-02-09 07:07

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