Coverage Report

Created: 2022-10-14 11:19

/src/php-src/ext/standard/sha1.c
Line
Count
Source (jump to first uncovered line)
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
   | http://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: Stefan Esser <sesser@php.net>                                |
14
   +----------------------------------------------------------------------+
15
*/
16
17
#include "php.h"
18
19
/* This code is heavily based on the PHP md5 implementation */
20
21
#include "sha1.h"
22
#include "md5.h"
23
24
PHPAPI void make_sha1_digest(char *sha1str, const unsigned char *digest)
25
0
{
26
0
  make_digest_ex(sha1str, digest, 20);
27
0
}
28
29
/* {{{ proto string sha1(string str [, bool raw_output])
30
   Calculate the sha1 hash of a string */
31
PHP_FUNCTION(sha1)
32
0
{
33
0
  zend_string *arg;
34
0
  zend_bool raw_output = 0;
35
0
  PHP_SHA1_CTX context;
36
0
  unsigned char digest[20];
37
38
0
  ZEND_PARSE_PARAMETERS_START(1, 2)
39
0
    Z_PARAM_STR(arg)
40
0
    Z_PARAM_OPTIONAL
41
0
    Z_PARAM_BOOL(raw_output)
42
0
  ZEND_PARSE_PARAMETERS_END();
43
44
0
  PHP_SHA1Init(&context);
45
0
  PHP_SHA1Update(&context, (unsigned char *) ZSTR_VAL(arg), ZSTR_LEN(arg));
46
0
  PHP_SHA1Final(digest, &context);
47
0
  if (raw_output) {
48
0
    RETURN_STRINGL((char *) digest, 20);
49
0
  } else {
50
0
    RETVAL_NEW_STR(zend_string_alloc(40, 0));
51
0
    make_digest_ex(Z_STRVAL_P(return_value), digest, 20);
52
0
  }
53
54
0
}
55
56
/* }}} */
57
58
59
/* {{{ proto string sha1_file(string filename [, bool raw_output])
60
   Calculate the sha1 hash of given filename */
61
PHP_FUNCTION(sha1_file)
62
0
{
63
0
  char          *arg;
64
0
  size_t           arg_len;
65
0
  zend_bool raw_output = 0;
66
0
  unsigned char buf[1024];
67
0
  unsigned char digest[20];
68
0
  PHP_SHA1_CTX   context;
69
0
  ssize_t        n;
70
0
  php_stream    *stream;
71
72
0
  ZEND_PARSE_PARAMETERS_START(1, 2)
73
0
    Z_PARAM_PATH(arg, arg_len)
74
0
    Z_PARAM_OPTIONAL
75
0
    Z_PARAM_BOOL(raw_output)
76
0
  ZEND_PARSE_PARAMETERS_END();
77
78
0
  stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, NULL);
79
0
  if (!stream) {
80
0
    RETURN_FALSE;
81
0
  }
82
83
0
  PHP_SHA1Init(&context);
84
85
0
  while ((n = php_stream_read(stream, (char *) buf, sizeof(buf))) > 0) {
86
0
    PHP_SHA1Update(&context, buf, n);
87
0
  }
88
89
0
  PHP_SHA1Final(digest, &context);
90
91
0
  php_stream_close(stream);
92
93
0
  if (raw_output) {
94
0
    RETURN_STRINGL((char *) digest, 20);
95
0
  } else {
96
0
    RETVAL_NEW_STR(zend_string_alloc(40, 0));
97
0
    make_digest_ex(Z_STRVAL_P(return_value), digest, 20);
98
0
  }
99
0
}
100
/* }}} */
101
102
103
static void SHA1Transform(uint32_t[5], const unsigned char[64]);
104
static void SHA1Encode(unsigned char *, uint32_t *, unsigned int);
105
static void SHA1Decode(uint32_t *, const unsigned char *, unsigned int);
106
107
static const unsigned char PADDING[64] =
108
{
109
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
112
};
113
114
/* F, G, H and I are basic SHA1 functions.
115
 */
116
0
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
117
0
#define G(x, y, z) ((x) ^ (y) ^ (z))
118
0
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
119
0
#define I(x, y, z) ((x) ^ (y) ^ (z))
120
121
/* ROTATE_LEFT rotates x left n bits.
122
 */
123
0
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
124
125
/* W[i]
126
 */
127
#define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
128
  (x[i&15]=ROTATE_LEFT(tmp, 1)) )
129
130
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
131
 */
132
0
#define FF(a, b, c, d, e, w) { \
133
0
 (e) += F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \
134
0
 (e) += ROTATE_LEFT ((a), 5); \
135
0
 (b) = ROTATE_LEFT((b), 30); \
136
0
  }
137
0
#define GG(a, b, c, d, e, w) { \
138
0
 (e) += G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \
139
0
 (e) += ROTATE_LEFT ((a), 5); \
140
0
 (b) = ROTATE_LEFT((b), 30); \
141
0
  }
142
0
#define HH(a, b, c, d, e, w) { \
143
0
 (e) += H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \
144
0
 (e) += ROTATE_LEFT ((a), 5); \
145
0
 (b) = ROTATE_LEFT((b), 30); \
146
0
  }
147
0
#define II(a, b, c, d, e, w) { \
148
0
 (e) += I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \
149
0
 (e) += ROTATE_LEFT ((a), 5); \
150
0
 (b) = ROTATE_LEFT((b), 30); \
151
0
  }
152
153
154
/* {{{ PHP_SHA1Init
155
 * SHA1 initialization. Begins an SHA1 operation, writing a new context.
156
 */
157
PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
158
0
{
159
0
  context->count[0] = context->count[1] = 0;
160
  /* Load magic initialization constants.
161
   */
162
0
  context->state[0] = 0x67452301;
163
0
  context->state[1] = 0xefcdab89;
164
0
  context->state[2] = 0x98badcfe;
165
0
  context->state[3] = 0x10325476;
166
0
  context->state[4] = 0xc3d2e1f0;
167
0
}
168
/* }}} */
169
170
/* {{{ PHP_SHA1Update
171
   SHA1 block update operation. Continues an SHA1 message-digest
172
   operation, processing another message block, and updating the
173
   context.
174
 */
175
PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
176
         size_t inputLen)
177
0
{
178
0
  unsigned int i, index, partLen;
179
180
  /* Compute number of bytes mod 64 */
181
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
182
183
  /* Update number of bits */
184
0
  if ((context->count[0] += ((uint32_t) inputLen << 3))
185
0
    < ((uint32_t) inputLen << 3))
186
0
    context->count[1]++;
187
0
  context->count[1] += ((uint32_t) inputLen >> 29);
188
189
0
  partLen = 64 - index;
190
191
  /* Transform as many times as possible.
192
   */
193
0
  if (inputLen >= partLen) {
194
0
    memcpy
195
0
      ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
196
0
    SHA1Transform(context->state, context->buffer);
197
198
0
    for (i = partLen; i + 63 < inputLen; i += 64)
199
0
      SHA1Transform(context->state, &input[i]);
200
201
0
    index = 0;
202
0
  } else
203
0
    i = 0;
204
205
  /* Buffer remaining input */
206
0
  memcpy
207
0
    ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
208
0
     inputLen - i);
209
0
}
210
/* }}} */
211
212
/* {{{ PHP_SHA1Final
213
   SHA1 finalization. Ends an SHA1 message-digest operation, writing the
214
   the message digest and zeroizing the context.
215
 */
216
PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
217
0
{
218
0
  unsigned char bits[8];
219
0
  unsigned int index, padLen;
220
221
  /* Save number of bits */
222
0
  bits[7] = context->count[0] & 0xFF;
223
0
  bits[6] = (context->count[0] >> 8) & 0xFF;
224
0
  bits[5] = (context->count[0] >> 16) & 0xFF;
225
0
  bits[4] = (context->count[0] >> 24) & 0xFF;
226
0
  bits[3] = context->count[1] & 0xFF;
227
0
  bits[2] = (context->count[1] >> 8) & 0xFF;
228
0
  bits[1] = (context->count[1] >> 16) & 0xFF;
229
0
  bits[0] = (context->count[1] >> 24) & 0xFF;
230
231
  /* Pad out to 56 mod 64.
232
   */
233
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
234
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
235
0
  PHP_SHA1Update(context, PADDING, padLen);
236
237
  /* Append length (before padding) */
238
0
  PHP_SHA1Update(context, bits, 8);
239
240
  /* Store state in digest */
241
0
  SHA1Encode(digest, context->state, 20);
242
243
  /* Zeroize sensitive information.
244
   */
245
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
246
0
}
247
/* }}} */
248
249
/* {{{ SHA1Transform
250
 * SHA1 basic transformation. Transforms state based on block.
251
 */
252
static void SHA1Transform(state, block)
253
uint32_t state[5];
254
const unsigned char block[64];
255
0
{
256
0
  uint32_t a = state[0], b = state[1], c = state[2];
257
0
  uint32_t d = state[3], e = state[4], x[16], tmp;
258
259
0
  SHA1Decode(x, block, 64);
260
261
  /* Round 1 */
262
0
  FF(a, b, c, d, e, x[0]);   /* 1 */
263
0
  FF(e, a, b, c, d, x[1]);   /* 2 */
264
0
  FF(d, e, a, b, c, x[2]);   /* 3 */
265
0
  FF(c, d, e, a, b, x[3]);   /* 4 */
266
0
  FF(b, c, d, e, a, x[4]);   /* 5 */
267
0
  FF(a, b, c, d, e, x[5]);   /* 6 */
268
0
  FF(e, a, b, c, d, x[6]);   /* 7 */
269
0
  FF(d, e, a, b, c, x[7]);   /* 8 */
270
0
  FF(c, d, e, a, b, x[8]);   /* 9 */
271
0
  FF(b, c, d, e, a, x[9]);   /* 10 */
272
0
  FF(a, b, c, d, e, x[10]);  /* 11 */
273
0
  FF(e, a, b, c, d, x[11]);  /* 12 */
274
0
  FF(d, e, a, b, c, x[12]);  /* 13 */
275
0
  FF(c, d, e, a, b, x[13]);  /* 14 */
276
0
  FF(b, c, d, e, a, x[14]);  /* 15 */
277
0
  FF(a, b, c, d, e, x[15]);  /* 16 */
278
0
  FF(e, a, b, c, d, W(16));  /* 17 */
279
0
  FF(d, e, a, b, c, W(17));  /* 18 */
280
0
  FF(c, d, e, a, b, W(18));  /* 19 */
281
0
  FF(b, c, d, e, a, W(19));  /* 20 */
282
283
  /* Round 2 */
284
0
  GG(a, b, c, d, e, W(20));  /* 21 */
285
0
  GG(e, a, b, c, d, W(21));  /* 22 */
286
0
  GG(d, e, a, b, c, W(22));  /* 23 */
287
0
  GG(c, d, e, a, b, W(23));  /* 24 */
288
0
  GG(b, c, d, e, a, W(24));  /* 25 */
289
0
  GG(a, b, c, d, e, W(25));  /* 26 */
290
0
  GG(e, a, b, c, d, W(26));  /* 27 */
291
0
  GG(d, e, a, b, c, W(27));  /* 28 */
292
0
  GG(c, d, e, a, b, W(28));  /* 29 */
293
0
  GG(b, c, d, e, a, W(29));  /* 30 */
294
0
  GG(a, b, c, d, e, W(30));  /* 31 */
295
0
  GG(e, a, b, c, d, W(31));  /* 32 */
296
0
  GG(d, e, a, b, c, W(32));  /* 33 */
297
0
  GG(c, d, e, a, b, W(33));  /* 34 */
298
0
  GG(b, c, d, e, a, W(34));  /* 35 */
299
0
  GG(a, b, c, d, e, W(35));  /* 36 */
300
0
  GG(e, a, b, c, d, W(36));  /* 37 */
301
0
  GG(d, e, a, b, c, W(37));  /* 38 */
302
0
  GG(c, d, e, a, b, W(38));  /* 39 */
303
0
  GG(b, c, d, e, a, W(39));  /* 40 */
304
305
  /* Round 3 */
306
0
  HH(a, b, c, d, e, W(40));  /* 41 */
307
0
  HH(e, a, b, c, d, W(41));  /* 42 */
308
0
  HH(d, e, a, b, c, W(42));  /* 43 */
309
0
  HH(c, d, e, a, b, W(43));  /* 44 */
310
0
  HH(b, c, d, e, a, W(44));  /* 45 */
311
0
  HH(a, b, c, d, e, W(45));  /* 46 */
312
0
  HH(e, a, b, c, d, W(46));  /* 47 */
313
0
  HH(d, e, a, b, c, W(47));  /* 48 */
314
0
  HH(c, d, e, a, b, W(48));  /* 49 */
315
0
  HH(b, c, d, e, a, W(49));  /* 50 */
316
0
  HH(a, b, c, d, e, W(50));  /* 51 */
317
0
  HH(e, a, b, c, d, W(51));  /* 52 */
318
0
  HH(d, e, a, b, c, W(52));  /* 53 */
319
0
  HH(c, d, e, a, b, W(53));  /* 54 */
320
0
  HH(b, c, d, e, a, W(54));  /* 55 */
321
0
  HH(a, b, c, d, e, W(55));  /* 56 */
322
0
  HH(e, a, b, c, d, W(56));  /* 57 */
323
0
  HH(d, e, a, b, c, W(57));  /* 58 */
324
0
  HH(c, d, e, a, b, W(58));  /* 59 */
325
0
  HH(b, c, d, e, a, W(59));  /* 60 */
326
327
  /* Round 4 */
328
0
  II(a, b, c, d, e, W(60));  /* 61 */
329
0
  II(e, a, b, c, d, W(61));  /* 62 */
330
0
  II(d, e, a, b, c, W(62));  /* 63 */
331
0
  II(c, d, e, a, b, W(63));  /* 64 */
332
0
  II(b, c, d, e, a, W(64));  /* 65 */
333
0
  II(a, b, c, d, e, W(65));  /* 66 */
334
0
  II(e, a, b, c, d, W(66));  /* 67 */
335
0
  II(d, e, a, b, c, W(67));  /* 68 */
336
0
  II(c, d, e, a, b, W(68));  /* 69 */
337
0
  II(b, c, d, e, a, W(69));  /* 70 */
338
0
  II(a, b, c, d, e, W(70));  /* 71 */
339
0
  II(e, a, b, c, d, W(71));  /* 72 */
340
0
  II(d, e, a, b, c, W(72));  /* 73 */
341
0
  II(c, d, e, a, b, W(73));  /* 74 */
342
0
  II(b, c, d, e, a, W(74));  /* 75 */
343
0
  II(a, b, c, d, e, W(75));  /* 76 */
344
0
  II(e, a, b, c, d, W(76));  /* 77 */
345
0
  II(d, e, a, b, c, W(77));  /* 78 */
346
0
  II(c, d, e, a, b, W(78));  /* 79 */
347
0
  II(b, c, d, e, a, W(79));  /* 80 */
348
349
0
  state[0] += a;
350
0
  state[1] += b;
351
0
  state[2] += c;
352
0
  state[3] += d;
353
0
  state[4] += e;
354
355
  /* Zeroize sensitive information. */
356
0
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
357
0
}
358
/* }}} */
359
360
/* {{{ SHA1Encode
361
   Encodes input (uint32_t) into output (unsigned char). Assumes len is
362
   a multiple of 4.
363
 */
364
static void SHA1Encode(output, input, len)
365
unsigned char *output;
366
uint32_t *input;
367
unsigned int len;
368
0
{
369
0
  unsigned int i, j;
370
371
0
  for (i = 0, j = 0; j < len; i++, j += 4) {
372
0
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
373
0
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
374
0
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
375
0
    output[j + 3] = (unsigned char) (input[i] & 0xff);
376
0
  }
377
0
}
378
/* }}} */
379
380
/* {{{ SHA1Decode
381
   Decodes input (unsigned char) into output (uint32_t). Assumes len is
382
   a multiple of 4.
383
 */
384
static void SHA1Decode(output, input, len)
385
uint32_t *output;
386
const unsigned char *input;
387
unsigned int len;
388
0
{
389
0
  unsigned int i, j;
390
391
0
  for (i = 0, j = 0; j < len; i++, j += 4)
392
0
    output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
393
0
      (((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
394
0
}
395
/* }}} */