Coverage Report

Created: 2022-02-19 20:31

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