Coverage Report

Created: 2026-06-02 06:39

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 © The PHP Group and Contributors.                          |
4
  +----------------------------------------------------------------------+
5
  | This source file is subject to the Modified BSD License that is      |
6
  | bundled with this package in the file LICENSE, and is available      |
7
  | through the World Wide Web at <https://www.php.net/license/>.        |
8
  |                                                                      |
9
  | SPDX-License-Identifier: BSD-3-Clause                                |
10
  +----------------------------------------------------------------------+
11
  | Author: Sara Golemon <pollita@php.net>                               |
12
  +----------------------------------------------------------------------+
13
*/
14
15
/* Heavily borrowed from md5.c & sha1.c of PHP archival fame
16
   Note that ripemd laughs in the face of logic and uses
17
   little endian byte ordering */
18
19
#include "php_hash.h"
20
#include "php_hash_ripemd.h"
21
22
const php_hash_ops php_hash_ripemd128_ops = {
23
  "ripemd128",
24
  (php_hash_init_func_t) PHP_RIPEMD128Init,
25
  (php_hash_update_func_t) PHP_RIPEMD128Update,
26
  (php_hash_final_func_t) PHP_RIPEMD128Final,
27
  php_hash_copy,
28
  php_hash_serialize,
29
  php_hash_unserialize,
30
  PHP_RIPEMD128_SPEC,
31
  16,
32
  64,
33
  sizeof(PHP_RIPEMD128_CTX),
34
  1
35
};
36
37
const php_hash_ops php_hash_ripemd160_ops = {
38
  "ripemd160",
39
  (php_hash_init_func_t) PHP_RIPEMD160Init,
40
  (php_hash_update_func_t) PHP_RIPEMD160Update,
41
  (php_hash_final_func_t) PHP_RIPEMD160Final,
42
  php_hash_copy,
43
  php_hash_serialize,
44
  php_hash_unserialize,
45
  PHP_RIPEMD160_SPEC,
46
  20,
47
  64,
48
  sizeof(PHP_RIPEMD160_CTX),
49
  1
50
};
51
52
const php_hash_ops php_hash_ripemd256_ops = {
53
  "ripemd256",
54
  (php_hash_init_func_t) PHP_RIPEMD256Init,
55
  (php_hash_update_func_t) PHP_RIPEMD256Update,
56
  (php_hash_final_func_t) PHP_RIPEMD256Final,
57
  php_hash_copy,
58
  php_hash_serialize,
59
  php_hash_unserialize,
60
  PHP_RIPEMD256_SPEC,
61
  32,
62
  64,
63
  sizeof(PHP_RIPEMD256_CTX),
64
  1
65
};
66
67
const php_hash_ops php_hash_ripemd320_ops = {
68
  "ripemd320",
69
  (php_hash_init_func_t) PHP_RIPEMD320Init,
70
  (php_hash_update_func_t) PHP_RIPEMD320Update,
71
  (php_hash_final_func_t) PHP_RIPEMD320Final,
72
  php_hash_copy,
73
  php_hash_serialize,
74
  php_hash_unserialize,
75
  PHP_RIPEMD320_SPEC,
76
  40,
77
  64,
78
  sizeof(PHP_RIPEMD320_CTX),
79
  1
80
};
81
82
/* {{{ PHP_RIPEMD128Init
83
 * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
84
 */
85
PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
86
0
{
87
0
  context->count[0] = context->count[1] = 0;
88
  /* Load magic initialization constants.
89
   */
90
0
  context->state[0] = 0x67452301;
91
0
  context->state[1] = 0xEFCDAB89;
92
0
  context->state[2] = 0x98BADCFE;
93
0
  context->state[3] = 0x10325476;
94
0
}
95
/* }}} */
96
97
/* {{{ PHP_RIPEMD256Init
98
 * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
99
 */
100
PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
101
0
{
102
0
  context->count[0] = context->count[1] = 0;
103
  /* Load magic initialization constants.
104
   */
105
0
  context->state[0] = 0x67452301;
106
0
  context->state[1] = 0xEFCDAB89;
107
0
  context->state[2] = 0x98BADCFE;
108
0
  context->state[3] = 0x10325476;
109
0
  context->state[4] = 0x76543210;
110
0
  context->state[5] = 0xFEDCBA98;
111
0
  context->state[6] = 0x89ABCDEF;
112
0
  context->state[7] = 0x01234567;
113
0
}
114
/* }}} */
115
116
/* {{{ PHP_RIPEMD160Init
117
 * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
118
 */
119
PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
120
0
{
121
0
  context->count[0] = context->count[1] = 0;
122
  /* Load magic initialization constants.
123
   */
124
0
  context->state[0] = 0x67452301;
125
0
  context->state[1] = 0xEFCDAB89;
126
0
  context->state[2] = 0x98BADCFE;
127
0
  context->state[3] = 0x10325476;
128
0
  context->state[4] = 0xC3D2E1F0;
129
0
}
130
/* }}} */
131
132
/* {{{ PHP_RIPEMD320Init
133
 * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
134
 */
135
PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
136
0
{
137
0
  context->count[0] = context->count[1] = 0;
138
  /* Load magic initialization constants.
139
   */
140
0
  context->state[0] = 0x67452301;
141
0
  context->state[1] = 0xEFCDAB89;
142
0
  context->state[2] = 0x98BADCFE;
143
0
  context->state[3] = 0x10325476;
144
0
  context->state[4] = 0xC3D2E1F0;
145
0
  context->state[5] = 0x76543210;
146
0
  context->state[6] = 0xFEDCBA98;
147
0
  context->state[7] = 0x89ABCDEF;
148
0
  context->state[8] = 0x01234567;
149
0
  context->state[9] = 0x3C2D1E0F;
150
0
}
151
/* }}} */
152
153
/* Basic ripemd function */
154
#define F0(x,y,z)   ((x) ^ (y) ^ (z))
155
#define F1(x,y,z)   (((x) & (y)) | ((~(x)) & (z)))
156
#define F2(x,y,z)   (((x) | (~(y))) ^ (z))
157
#define F3(x,y,z)   (((x) & (z)) | ((y) & (~(z))))
158
#define F4(x,y,z)   ((x) ^ ((y) | (~(z))))
159
160
static const uint32_t K_values[5]  = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E };    /* 128, 256, 160, 320 */
161
static const uint32_t KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 };                /* 128 & 256 */
162
static const uint32_t KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
163
164
#define K(n)  K_values[ (n) >> 4]
165
#define KK(n) KK_values[(n) >> 4]
166
#define KK160(n) KK160_values[(n) >> 4]
167
168
static const unsigned char R[80] = {
169
   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
170
   7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
171
   3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
172
   1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
173
   4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13 };
174
175
static const unsigned char RR[80] = {
176
   5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
177
   6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
178
  15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
179
   8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
180
  12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11 };
181
182
static const unsigned char S[80] = {
183
  11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
184
   7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
185
  11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
186
  11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
187
   9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6 };
188
189
static const unsigned char SS[80] = {
190
   8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
191
   9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
192
   9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
193
  15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
194
   8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11 };
195
196
0
#define ROLS(j, x)  (((x) << S[j])  | ((x) >> (32 - S[j])))
197
0
#define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
198
0
#define ROL(n, x) (((x) << n) | ((x) >> (32 - n)))
199
200
/* {{{ RIPEMDDecode
201
   Decodes input (unsigned char) into output (uint32_t). Assumes len is
202
   a multiple of 4.
203
 */
204
static void RIPEMDDecode(uint32_t *output, const unsigned char *input, unsigned int len)
205
0
{
206
0
  unsigned int i, j;
207
208
0
  for (i = 0, j = 0; j < len; i++, j += 4)
209
0
    output[i] = ((uint32_t) input[j + 0]) | (((uint32_t) input[j + 1]) << 8) |
210
0
      (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
211
0
}
212
/* }}} */
213
214
/* {{{ RIPEMD128Transform
215
 * ripemd128 basic transformation. Transforms state based on block.
216
 */
217
static void RIPEMD128Transform(uint32_t state[4], const unsigned char block[64])
218
0
{
219
0
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3];
220
0
  uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3];
221
0
  uint32_t tmp, x[16];
222
0
  int j;
223
224
0
  RIPEMDDecode(x, block, 64);
225
226
0
  for(j = 0; j < 16; j++) {
227
0
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j));
228
0
    a = d; d = c; c = b; b = tmp;
229
0
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
230
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
231
0
  }
232
233
0
  for(j = 16; j < 32; j++) {
234
0
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j));
235
0
    a = d; d = c; c = b; b = tmp;
236
0
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
237
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
238
0
  }
239
240
0
  for(j = 32; j < 48; j++) {
241
0
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j));
242
0
    a = d; d = c; c = b; b = tmp;
243
0
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
244
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
245
0
  }
246
247
0
  for(j = 48; j < 64; j++) {
248
0
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j));
249
0
    a = d; d = c; c = b; b = tmp;
250
0
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
251
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
252
0
  }
253
254
0
  tmp = state[1] + c + dd;
255
0
  state[1] = state[2] + d + aa;
256
0
  state[2] = state[3] + a + bb;
257
0
  state[3] = state[0] + b + cc;
258
0
  state[0] = tmp;
259
260
0
  tmp = 0;
261
0
  ZEND_SECURE_ZERO(x, sizeof(x));
262
0
}
263
/* }}} */
264
265
/* {{{ PHP_RIPEMD128Update
266
   ripemd128 block update operation. Continues a ripemd128 message-digest
267
   operation, processing another message block, and updating the
268
   context.
269
 */
270
PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, size_t inputLen)
271
0
{
272
0
  unsigned int index, partLen;
273
0
  size_t i;
274
275
  /* Compute number of bytes mod 64 */
276
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
277
278
  /* Update number of bits */
279
0
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
280
0
    context->count[1]++;
281
0
  }
282
0
  context->count[1] += (uint32_t) (inputLen >> 29);
283
284
0
  partLen = 64 - index;
285
286
  /* Transform as many times as possible.
287
   */
288
0
  if (inputLen >= partLen) {
289
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
290
0
    RIPEMD128Transform(context->state, context->buffer);
291
292
0
    for (i = partLen; i + 63 < inputLen; i += 64) {
293
0
      RIPEMD128Transform(context->state, &input[i]);
294
0
    }
295
296
0
    index = 0;
297
0
  } else {
298
0
    i = 0;
299
0
  }
300
301
  /* Buffer remaining input */
302
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
303
0
}
304
/* }}} */
305
306
/* {{{ RIPEMD256Transform
307
 * ripemd256 basic transformation. Transforms state based on block.
308
 */
309
static void RIPEMD256Transform(uint32_t state[8], const unsigned char block[64])
310
0
{
311
0
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3];
312
0
  uint32_t aa = state[4], bb = state[5], cc = state[6], dd = state[7];
313
0
  uint32_t tmp, x[16];
314
0
  int j;
315
316
0
  RIPEMDDecode(x, block, 64);
317
318
0
  for(j = 0; j < 16; j++) {
319
0
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j));
320
0
    a = d; d = c; c = b; b = tmp;
321
0
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
322
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
323
0
  }
324
0
  tmp = a; a = aa; aa = tmp;
325
326
0
  for(j = 16; j < 32; j++) {
327
0
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j));
328
0
    a = d; d = c; c = b; b = tmp;
329
0
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
330
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
331
0
  }
332
0
  tmp = b; b = bb; bb = tmp;
333
334
0
  for(j = 32; j < 48; j++) {
335
0
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j));
336
0
    a = d; d = c; c = b; b = tmp;
337
0
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
338
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
339
0
  }
340
0
  tmp = c; c = cc; cc = tmp;
341
342
0
  for(j = 48; j < 64; j++) {
343
0
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j));
344
0
    a = d; d = c; c = b; b = tmp;
345
0
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
346
0
    aa = dd; dd = cc; cc = bb; bb = tmp;
347
0
  }
348
0
  tmp = d; d = dd; dd = tmp;
349
350
0
  state[0] += a;
351
0
  state[1] += b;
352
0
  state[2] += c;
353
0
  state[3] += d;
354
0
  state[4] += aa;
355
0
  state[5] += bb;
356
0
  state[6] += cc;
357
0
  state[7] += dd;
358
359
0
  tmp = 0;
360
0
  ZEND_SECURE_ZERO(x, sizeof(x));
361
0
}
362
/* }}} */
363
364
/* {{{ PHP_RIPEMD256Update
365
   ripemd256 block update operation. Continues a ripemd256 message-digest
366
   operation, processing another message block, and updating the
367
   context.
368
 */
369
PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, size_t inputLen)
370
0
{
371
0
  unsigned int index, partLen;
372
0
  size_t i;
373
374
  /* Compute number of bytes mod 64 */
375
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
376
377
  /* Update number of bits */
378
0
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
379
0
    context->count[1]++;
380
0
  }
381
0
  context->count[1] += (uint32_t) (inputLen >> 29);
382
383
0
  partLen = 64 - index;
384
385
  /* Transform as many times as possible.
386
   */
387
0
  if (inputLen >= partLen) {
388
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
389
0
    RIPEMD256Transform(context->state, context->buffer);
390
391
0
    for (i = partLen; i + 63 < inputLen; i += 64) {
392
0
      RIPEMD256Transform(context->state, &input[i]);
393
0
    }
394
395
0
    index = 0;
396
0
  } else {
397
0
    i = 0;
398
0
  }
399
400
  /* Buffer remaining input */
401
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
402
0
}
403
/* }}} */
404
405
/* {{{ RIPEMD160Transform
406
 * ripemd160 basic transformation. Transforms state based on block.
407
 */
408
static void RIPEMD160Transform(uint32_t state[5], const unsigned char block[64])
409
0
{
410
0
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3], e  = state[4];
411
0
  uint32_t aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
412
0
  uint32_t tmp, x[16];
413
0
  int j;
414
415
0
  RIPEMDDecode(x, block, 64);
416
417
0
  for(j = 0; j < 16; j++) {
418
0
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j)) + e;
419
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
420
0
    tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
421
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
422
0
  }
423
424
0
  for(j = 16; j < 32; j++) {
425
0
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j)) + e;
426
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
427
0
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
428
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
429
0
  }
430
431
0
  for(j = 32; j < 48; j++) {
432
0
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j)) + e;
433
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
434
0
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
435
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
436
0
  }
437
438
0
  for(j = 48; j < 64; j++) {
439
0
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j)) + e;
440
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
441
0
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
442
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
443
0
  }
444
445
0
  for(j = 64; j < 80; j++) {
446
0
    tmp = ROLS( j, a  + F4(b,  c,  d)  + x[R[j]]  + K(j)) + e;
447
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
448
0
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
449
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
450
0
  }
451
452
0
  tmp = state[1] + c + dd;
453
0
  state[1] = state[2] + d + ee;
454
0
  state[2] = state[3] + e + aa;
455
0
  state[3] = state[4] + a + bb;
456
0
  state[4] = state[0] + b + cc;
457
0
  state[0] = tmp;
458
459
0
  tmp = 0;
460
0
  ZEND_SECURE_ZERO(x, sizeof(x));
461
0
}
462
/* }}} */
463
464
/* {{{ PHP_RIPEMD160Update
465
   ripemd160 block update operation. Continues a ripemd160 message-digest
466
   operation, processing another message block, and updating the
467
   context.
468
 */
469
PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, size_t inputLen)
470
0
{
471
0
  unsigned int index, partLen;
472
0
  size_t i;
473
474
  /* Compute number of bytes mod 64 */
475
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
476
477
  /* Update number of bits */
478
0
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
479
0
    context->count[1]++;
480
0
  }
481
0
  context->count[1] += (uint32_t) (inputLen >> 29);
482
483
0
  partLen = 64 - index;
484
485
  /* Transform as many times as possible.
486
   */
487
0
  if (inputLen >= partLen) {
488
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
489
0
    RIPEMD160Transform(context->state, context->buffer);
490
491
0
    for (i = partLen; i + 63 < inputLen; i += 64) {
492
0
      RIPEMD160Transform(context->state, &input[i]);
493
0
    }
494
495
0
    index = 0;
496
0
  } else {
497
0
    i = 0;
498
0
  }
499
500
  /* Buffer remaining input */
501
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
502
0
}
503
/* }}} */
504
505
/* {{{ RIPEMD320Transform
506
 * ripemd320 basic transformation. Transforms state based on block.
507
 */
508
static void RIPEMD320Transform(uint32_t state[10], const unsigned char block[64])
509
0
{
510
0
  uint32_t a  = state[0], b  = state[1], c  = state[2], d  = state[3], e  = state[4];
511
0
  uint32_t aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
512
0
  uint32_t tmp, x[16];
513
0
  int j;
514
515
0
  RIPEMDDecode(x, block, 64);
516
517
0
  for(j = 0; j < 16; j++) {
518
0
    tmp = ROLS( j, a  + F0(b,  c,  d)  + x[R[j]]  + K(j)) + e;
519
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
520
0
    tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
521
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
522
0
  }
523
0
  tmp = b; b = bb; bb = tmp;
524
525
0
  for(j = 16; j < 32; j++) {
526
0
    tmp = ROLS( j, a  + F1(b,  c,  d)  + x[R[j]]  + K(j)) + e;
527
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
528
0
    tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
529
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
530
0
  }
531
0
  tmp = d; d = dd; dd = tmp;
532
533
0
  for(j = 32; j < 48; j++) {
534
0
    tmp = ROLS( j, a  + F2(b,  c,  d)  + x[R[j]]  + K(j)) + e;
535
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
536
0
    tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
537
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
538
0
  }
539
0
  tmp = a; a = aa; aa = tmp;
540
541
0
  for(j = 48; j < 64; j++) {
542
0
    tmp = ROLS( j, a  + F3(b,  c,  d)  + x[R[j]]  + K(j)) + e;
543
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
544
0
    tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
545
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
546
0
  }
547
0
  tmp = c; c = cc; cc = tmp;
548
549
0
  for(j = 64; j < 80; j++) {
550
0
    tmp = ROLS( j, a  + F4(b,  c,  d)  + x[R[j]]  + K(j)) + e;
551
0
    a = e; e = d; d = ROL(10, c); c = b; b = tmp;
552
0
    tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
553
0
    aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
554
0
  }
555
0
  tmp = e; e = ee; ee = tmp;
556
557
0
  state[0] += a;
558
0
  state[1] += b;
559
0
  state[2] += c;
560
0
  state[3] += d;
561
0
  state[4] += e;
562
0
  state[5] += aa;
563
0
  state[6] += bb;
564
0
  state[7] += cc;
565
0
  state[8] += dd;
566
0
  state[9] += ee;
567
568
0
  tmp = 0;
569
0
  ZEND_SECURE_ZERO(x, sizeof(x));
570
0
}
571
/* }}} */
572
573
/* {{{ PHP_RIPEMD320Update
574
   ripemd320 block update operation. Continues a ripemd320 message-digest
575
   operation, processing another message block, and updating the
576
   context.
577
 */
578
PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, size_t inputLen)
579
0
{
580
0
  unsigned int index, partLen;
581
0
  size_t i;
582
583
  /* Compute number of bytes mod 64 */
584
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
585
586
  /* Update number of bits */
587
0
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
588
0
    context->count[1]++;
589
0
  }
590
0
  context->count[1] += (uint32_t) (inputLen >> 29);
591
592
0
  partLen = 64 - index;
593
594
  /* Transform as many times as possible.
595
   */
596
0
  if (inputLen >= partLen) {
597
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
598
0
    RIPEMD320Transform(context->state, context->buffer);
599
600
0
    for (i = partLen; i + 63 < inputLen; i += 64) {
601
0
      RIPEMD320Transform(context->state, &input[i]);
602
0
    }
603
604
0
    index = 0;
605
0
  } else {
606
0
    i = 0;
607
0
  }
608
609
  /* Buffer remaining input */
610
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
611
0
}
612
/* }}} */
613
614
static const unsigned char PADDING[64] =
615
{
616
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
617
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
619
};
620
621
/* {{{ RIPEMDEncode
622
   Encodes input (uint32_t) into output (unsigned char). Assumes len is
623
   a multiple of 4.
624
 */
625
static void RIPEMDEncode(unsigned char *output, uint32_t *input, unsigned int len)
626
0
{
627
0
  unsigned int i, j;
628
629
0
  for (i = 0, j = 0; j < len; i++, j += 4) {
630
0
    output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
631
0
    output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
632
0
    output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
633
0
    output[j + 0] = (unsigned char) (input[i] & 0xff);
634
0
  }
635
0
}
636
/* }}} */
637
638
/* {{{ PHP_RIPEMD128Final
639
   ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
640
   the message digest and zeroizing the context.
641
 */
642
PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
643
0
{
644
0
  unsigned char bits[8];
645
0
  unsigned int index, padLen;
646
647
  /* Save number of bits */
648
0
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
649
0
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
650
0
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
651
0
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
652
0
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
653
0
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
654
0
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
655
0
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
656
657
  /* Pad out to 56 mod 64.
658
   */
659
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
660
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
661
0
  PHP_RIPEMD128Update(context, PADDING, padLen);
662
663
  /* Append length (before padding) */
664
0
  PHP_RIPEMD128Update(context, bits, 8);
665
666
  /* Store state in digest */
667
0
  RIPEMDEncode(digest, context->state, 16);
668
669
  /* Zeroize sensitive information.
670
   */
671
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
672
0
}
673
/* }}} */
674
675
/* {{{ PHP_RIPEMD256Final
676
   ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
677
   the message digest and zeroizing the context.
678
 */
679
PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
680
0
{
681
0
  unsigned char bits[8];
682
0
  unsigned int index, padLen;
683
684
  /* Save number of bits */
685
0
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
686
0
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
687
0
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
688
0
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
689
0
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
690
0
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
691
0
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
692
0
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
693
694
  /* Pad out to 56 mod 64.
695
   */
696
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
697
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
698
0
  PHP_RIPEMD256Update(context, PADDING, padLen);
699
700
  /* Append length (before padding) */
701
0
  PHP_RIPEMD256Update(context, bits, 8);
702
703
  /* Store state in digest */
704
0
  RIPEMDEncode(digest, context->state, 32);
705
706
  /* Zeroize sensitive information.
707
   */
708
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
709
0
}
710
/* }}} */
711
712
/* {{{ PHP_RIPEMD160Final
713
   ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
714
   the message digest and zeroizing the context.
715
 */
716
PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
717
0
{
718
0
  unsigned char bits[8];
719
0
  unsigned int index, padLen;
720
721
  /* Save number of bits */
722
0
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
723
0
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
724
0
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
725
0
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
726
0
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
727
0
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
728
0
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
729
0
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
730
731
  /* Pad out to 56 mod 64.
732
   */
733
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
734
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
735
0
  PHP_RIPEMD160Update(context, PADDING, padLen);
736
737
  /* Append length (before padding) */
738
0
  PHP_RIPEMD160Update(context, bits, 8);
739
740
  /* Store state in digest */
741
0
  RIPEMDEncode(digest, context->state, 20);
742
743
  /* Zeroize sensitive information.
744
   */
745
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
746
0
}
747
/* }}} */
748
749
/* {{{ PHP_RIPEMD320Final
750
   ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
751
   the message digest and zeroizing the context.
752
 */
753
PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
754
0
{
755
0
  unsigned char bits[8];
756
0
  unsigned int index, padLen;
757
758
  /* Save number of bits */
759
0
  bits[0] = (unsigned char) (context->count[0] & 0xFF);
760
0
  bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
761
0
  bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
762
0
  bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
763
0
  bits[4] = (unsigned char) (context->count[1] & 0xFF);
764
0
  bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
765
0
  bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
766
0
  bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
767
768
  /* Pad out to 56 mod 64.
769
   */
770
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
771
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
772
0
  PHP_RIPEMD320Update(context, PADDING, padLen);
773
774
  /* Append length (before padding) */
775
0
  PHP_RIPEMD320Update(context, bits, 8);
776
777
  /* Store state in digest */
778
0
  RIPEMDEncode(digest, context->state, 40);
779
780
  /* Zeroize sensitive information.
781
   */
782
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
783
0
}
784
/* }}} */