Coverage Report

Created: 2026-06-02 06:37

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