Coverage Report

Created: 2025-09-27 06:26

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