Coverage Report

Created: 2025-12-14 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/standard/sha1.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: 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
  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
  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
1.02M
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
115
1.02M
#define G(x, y, z) ((x) ^ (y) ^ (z))
116
1.02M
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
117
1.02M
#define I(x, y, z) ((x) ^ (y) ^ (z))
118
119
/* ROTATE_LEFT rotates x left n bits.
120
 */
121
8.22M
#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
1.02M
#define FF(a, b, c, d, e, w) { \
131
1.02M
 (e) += F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \
132
1.02M
 (e) += ROTATE_LEFT ((a), 5); \
133
1.02M
 (b) = ROTATE_LEFT((b), 30); \
134
1.02M
  }
135
1.02M
#define GG(a, b, c, d, e, w) { \
136
1.02M
 (e) += G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \
137
1.02M
 (e) += ROTATE_LEFT ((a), 5); \
138
1.02M
 (b) = ROTATE_LEFT((b), 30); \
139
1.02M
  }
140
1.02M
#define HH(a, b, c, d, e, w) { \
141
1.02M
 (e) += H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \
142
1.02M
 (e) += ROTATE_LEFT ((a), 5); \
143
1.02M
 (b) = ROTATE_LEFT((b), 30); \
144
1.02M
  }
145
1.02M
#define II(a, b, c, d, e, w) { \
146
1.02M
 (e) += I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \
147
1.02M
 (e) += ROTATE_LEFT ((a), 5); \
148
1.02M
 (b) = ROTATE_LEFT((b), 30); \
149
1.02M
  }
150
151
152
/* {{{ PHP_SHA1Init
153
 * SHA1 initialization. Begins an SHA1 operation, writing a new context.
154
 */
155
PHPAPI void PHP_SHA1InitArgs(PHP_SHA1_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
156
99
{
157
99
  context->count[0] = context->count[1] = 0;
158
  /* Load magic initialization constants.
159
   */
160
99
  context->state[0] = 0x67452301;
161
99
  context->state[1] = 0xefcdab89;
162
99
  context->state[2] = 0x98badcfe;
163
99
  context->state[3] = 0x10325476;
164
99
  context->state[4] = 0xc3d2e1f0;
165
99
}
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
297
{
176
297
  unsigned int index, partLen;
177
297
  size_t i;
178
179
  /* Compute number of bytes mod 64 */
180
297
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
181
182
  /* Update number of bits */
183
297
  if ((context->count[0] += ((uint32_t) inputLen << 3))
184
297
    < ((uint32_t) inputLen << 3))
185
12
    context->count[1]++;
186
297
  context->count[1] += (uint32_t) (inputLen >> 29);
187
188
297
  partLen = 64 - index;
189
190
  /* Transform as many times as possible.
191
   */
192
297
  if (inputLen >= partLen) {
193
195
    memcpy
194
195
      ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
195
195
    SHA1Transform(context->state, context->buffer);
196
197
51.4k
    for (i = partLen; i + 63 < inputLen; i += 64)
198
51.2k
      SHA1Transform(context->state, &input[i]);
199
200
195
    index = 0;
201
195
  } else
202
102
    i = 0;
203
204
  /* Buffer remaining input */
205
297
  memcpy
206
297
    ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
207
297
     inputLen - i);
208
297
}
209
/* }}} */
210
211
/* {{{ PHP_SHA1Final
212
   SHA1 finalization. Ends an SHA1 message-digest operation, writing the
213
   the message digest and zeroizing the context.
214
 */
215
PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
216
99
{
217
99
  unsigned char bits[8];
218
99
  unsigned int index, padLen;
219
220
  /* Save number of bits */
221
99
  bits[7] = context->count[0] & 0xFF;
222
99
  bits[6] = (context->count[0] >> 8) & 0xFF;
223
99
  bits[5] = (context->count[0] >> 16) & 0xFF;
224
99
  bits[4] = (context->count[0] >> 24) & 0xFF;
225
99
  bits[3] = context->count[1] & 0xFF;
226
99
  bits[2] = (context->count[1] >> 8) & 0xFF;
227
99
  bits[1] = (context->count[1] >> 16) & 0xFF;
228
99
  bits[0] = (context->count[1] >> 24) & 0xFF;
229
230
  /* Pad out to 56 mod 64.
231
   */
232
99
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
233
99
  padLen = (index < 56) ? (56 - index) : (120 - index);
234
99
  PHP_SHA1Update(context, PADDING, padLen);
235
236
  /* Append length (before padding) */
237
99
  PHP_SHA1Update(context, bits, 8);
238
239
  /* Store state in digest */
240
99
  SHA1Encode(digest, context->state, 20);
241
242
  /* Zeroize sensitive information.
243
   */
244
99
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
245
99
}
246
/* }}} */
247
248
/* {{{ SHA1Transform
249
 * SHA1 basic transformation. Transforms state based on block.
250
 */
251
static void SHA1Transform(uint32_t state[5], const unsigned char block[64])
252
51.4k
{
253
51.4k
  uint32_t a = state[0], b = state[1], c = state[2];
254
51.4k
  uint32_t d = state[3], e = state[4], x[16], tmp;
255
256
51.4k
  SHA1Decode(x, block, 64);
257
258
  /* Round 1 */
259
51.4k
  FF(a, b, c, d, e, x[0]);   /* 1 */
260
51.4k
  FF(e, a, b, c, d, x[1]);   /* 2 */
261
51.4k
  FF(d, e, a, b, c, x[2]);   /* 3 */
262
51.4k
  FF(c, d, e, a, b, x[3]);   /* 4 */
263
51.4k
  FF(b, c, d, e, a, x[4]);   /* 5 */
264
51.4k
  FF(a, b, c, d, e, x[5]);   /* 6 */
265
51.4k
  FF(e, a, b, c, d, x[6]);   /* 7 */
266
51.4k
  FF(d, e, a, b, c, x[7]);   /* 8 */
267
51.4k
  FF(c, d, e, a, b, x[8]);   /* 9 */
268
51.4k
  FF(b, c, d, e, a, x[9]);   /* 10 */
269
51.4k
  FF(a, b, c, d, e, x[10]);  /* 11 */
270
51.4k
  FF(e, a, b, c, d, x[11]);  /* 12 */
271
51.4k
  FF(d, e, a, b, c, x[12]);  /* 13 */
272
51.4k
  FF(c, d, e, a, b, x[13]);  /* 14 */
273
51.4k
  FF(b, c, d, e, a, x[14]);  /* 15 */
274
51.4k
  FF(a, b, c, d, e, x[15]);  /* 16 */
275
51.4k
  FF(e, a, b, c, d, W(16));  /* 17 */
276
51.4k
  FF(d, e, a, b, c, W(17));  /* 18 */
277
51.4k
  FF(c, d, e, a, b, W(18));  /* 19 */
278
51.4k
  FF(b, c, d, e, a, W(19));  /* 20 */
279
280
  /* Round 2 */
281
51.4k
  GG(a, b, c, d, e, W(20));  /* 21 */
282
51.4k
  GG(e, a, b, c, d, W(21));  /* 22 */
283
51.4k
  GG(d, e, a, b, c, W(22));  /* 23 */
284
51.4k
  GG(c, d, e, a, b, W(23));  /* 24 */
285
51.4k
  GG(b, c, d, e, a, W(24));  /* 25 */
286
51.4k
  GG(a, b, c, d, e, W(25));  /* 26 */
287
51.4k
  GG(e, a, b, c, d, W(26));  /* 27 */
288
51.4k
  GG(d, e, a, b, c, W(27));  /* 28 */
289
51.4k
  GG(c, d, e, a, b, W(28));  /* 29 */
290
51.4k
  GG(b, c, d, e, a, W(29));  /* 30 */
291
51.4k
  GG(a, b, c, d, e, W(30));  /* 31 */
292
51.4k
  GG(e, a, b, c, d, W(31));  /* 32 */
293
51.4k
  GG(d, e, a, b, c, W(32));  /* 33 */
294
51.4k
  GG(c, d, e, a, b, W(33));  /* 34 */
295
51.4k
  GG(b, c, d, e, a, W(34));  /* 35 */
296
51.4k
  GG(a, b, c, d, e, W(35));  /* 36 */
297
51.4k
  GG(e, a, b, c, d, W(36));  /* 37 */
298
51.4k
  GG(d, e, a, b, c, W(37));  /* 38 */
299
51.4k
  GG(c, d, e, a, b, W(38));  /* 39 */
300
51.4k
  GG(b, c, d, e, a, W(39));  /* 40 */
301
302
  /* Round 3 */
303
51.4k
  HH(a, b, c, d, e, W(40));  /* 41 */
304
51.4k
  HH(e, a, b, c, d, W(41));  /* 42 */
305
51.4k
  HH(d, e, a, b, c, W(42));  /* 43 */
306
51.4k
  HH(c, d, e, a, b, W(43));  /* 44 */
307
51.4k
  HH(b, c, d, e, a, W(44));  /* 45 */
308
51.4k
  HH(a, b, c, d, e, W(45));  /* 46 */
309
51.4k
  HH(e, a, b, c, d, W(46));  /* 47 */
310
51.4k
  HH(d, e, a, b, c, W(47));  /* 48 */
311
51.4k
  HH(c, d, e, a, b, W(48));  /* 49 */
312
51.4k
  HH(b, c, d, e, a, W(49));  /* 50 */
313
51.4k
  HH(a, b, c, d, e, W(50));  /* 51 */
314
51.4k
  HH(e, a, b, c, d, W(51));  /* 52 */
315
51.4k
  HH(d, e, a, b, c, W(52));  /* 53 */
316
51.4k
  HH(c, d, e, a, b, W(53));  /* 54 */
317
51.4k
  HH(b, c, d, e, a, W(54));  /* 55 */
318
51.4k
  HH(a, b, c, d, e, W(55));  /* 56 */
319
51.4k
  HH(e, a, b, c, d, W(56));  /* 57 */
320
51.4k
  HH(d, e, a, b, c, W(57));  /* 58 */
321
51.4k
  HH(c, d, e, a, b, W(58));  /* 59 */
322
51.4k
  HH(b, c, d, e, a, W(59));  /* 60 */
323
324
  /* Round 4 */
325
51.4k
  II(a, b, c, d, e, W(60));  /* 61 */
326
51.4k
  II(e, a, b, c, d, W(61));  /* 62 */
327
51.4k
  II(d, e, a, b, c, W(62));  /* 63 */
328
51.4k
  II(c, d, e, a, b, W(63));  /* 64 */
329
51.4k
  II(b, c, d, e, a, W(64));  /* 65 */
330
51.4k
  II(a, b, c, d, e, W(65));  /* 66 */
331
51.4k
  II(e, a, b, c, d, W(66));  /* 67 */
332
51.4k
  II(d, e, a, b, c, W(67));  /* 68 */
333
51.4k
  II(c, d, e, a, b, W(68));  /* 69 */
334
51.4k
  II(b, c, d, e, a, W(69));  /* 70 */
335
51.4k
  II(a, b, c, d, e, W(70));  /* 71 */
336
51.4k
  II(e, a, b, c, d, W(71));  /* 72 */
337
51.4k
  II(d, e, a, b, c, W(72));  /* 73 */
338
51.4k
  II(c, d, e, a, b, W(73));  /* 74 */
339
51.4k
  II(b, c, d, e, a, W(74));  /* 75 */
340
51.4k
  II(a, b, c, d, e, W(75));  /* 76 */
341
51.4k
  II(e, a, b, c, d, W(76));  /* 77 */
342
51.4k
  II(d, e, a, b, c, W(77));  /* 78 */
343
51.4k
  II(c, d, e, a, b, W(78));  /* 79 */
344
51.4k
  II(b, c, d, e, a, W(79));  /* 80 */
345
346
51.4k
  state[0] += a;
347
51.4k
  state[1] += b;
348
51.4k
  state[2] += c;
349
51.4k
  state[3] += d;
350
51.4k
  state[4] += e;
351
352
  /* Zeroize sensitive information. */
353
51.4k
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
354
51.4k
}
355
/* }}} */
356
357
/* {{{ SHA1Encode
358
   Encodes input (uint32_t) into output (unsigned char). Assumes len is
359
   a multiple of 4.
360
 */
361
static void SHA1Encode(unsigned char *output, uint32_t *input, unsigned int len)
362
99
{
363
99
  unsigned int i, j;
364
365
594
  for (i = 0, j = 0; j < len; i++, j += 4) {
366
495
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
367
495
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
368
495
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
369
495
    output[j + 3] = (unsigned char) (input[i] & 0xff);
370
495
  }
371
99
}
372
/* }}} */
373
374
/* {{{ SHA1Decode
375
   Decodes input (unsigned char) into output (uint32_t). Assumes len is
376
   a multiple of 4.
377
 */
378
static void SHA1Decode(uint32_t *output, const unsigned char *input, unsigned int len)
379
51.4k
{
380
51.4k
  unsigned int i, j;
381
382
873k
  for (i = 0, j = 0; j < len; i++, j += 4)
383
822k
    output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
384
822k
      (((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
385
51.4k
}
386
/* }}} */