Coverage Report

Created: 2025-11-16 06:23

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