Coverage Report

Created: 2025-12-31 07:28

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