Coverage Report

Created: 2025-12-31 07:28

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