Coverage Report

Created: 2025-12-14 06:05

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