Annotation of embedaddon/php/ext/hash/hash_sha.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Authors: Steffan Esser <sesser@php.net> |
16: | Sara Golemon <pollita@php.net> |
17: +----------------------------------------------------------------------+
18: */
19:
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 21:
22: #include "php_hash.h"
23: #include "php_hash_sha.h"
24:
25: static const unsigned char PADDING[128] =
26: {
27: 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
35: };
36:
37: /* {{{ SHAEncode32
38: Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
39: a multiple of 4.
40: */
41: static void SHAEncode32(unsigned char *output, php_hash_uint32 *input, unsigned int len)
42: {
43: unsigned int i, j;
44:
45: for (i = 0, j = 0; j < len; i++, j += 4) {
46: output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
47: output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
48: output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
49: output[j + 3] = (unsigned char) (input[i] & 0xff);
50: }
51: }
52: /* }}} */
53:
54:
55: /* {{{ SHADecode32
56: Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
57: a multiple of 4.
58: */
59: static void SHADecode32(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
60: {
61: unsigned int i, j;
62:
63: for (i = 0, j = 0; j < len; i++, j += 4)
64: output[i] = ((php_hash_uint32) input[j + 3]) | (((php_hash_uint32) input[j + 2]) << 8) |
65: (((php_hash_uint32) input[j + 1]) << 16) | (((php_hash_uint32) input[j]) << 24);
66: }
67: /* }}} */
68:
69: const php_hash_ops php_hash_sha1_ops = {
70: (php_hash_init_func_t) PHP_SHA1Init,
71: (php_hash_update_func_t) PHP_SHA1Update,
72: (php_hash_final_func_t) PHP_SHA1Final,
73: (php_hash_copy_func_t) php_hash_copy,
74: 20,
75: 64,
76: sizeof(PHP_SHA1_CTX)
77: };
78:
79: #ifdef PHP_HASH_SHA1_NOT_IN_CORE
80:
81: PHP_HASH_API void make_sha1_digest(char *sha1str, unsigned char *digest)
82: {
83: php_hash_bin2hex(sha1str, digest, 20);
84: sha1str[40] = '\0';
85: }
86:
87: /* {{{ proto string sha1(string str [, bool raw_output])
88: Calculate the sha1 hash of a string */
89: PHP_FUNCTION(sha1)
90: {
91: char *arg;
92: int arg_len;
93: zend_bool raw_output = 0;
94: char sha1str[41];
95: PHP_SHA1_CTX context;
96: unsigned char digest[20];
97:
98: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
99: return;
100: }
101:
102: sha1str[0] = '\0';
103: PHP_SHA1Init(&context);
104: PHP_SHA1Update(&context, arg, arg_len);
105: PHP_SHA1Final(digest, &context);
106: if (raw_output) {
107: RETURN_STRINGL(digest, 20, 1);
108: } else {
109: make_sha1_digest(sha1str, digest);
110: RETVAL_STRING(sha1str, 1);
111: }
112:
113: }
114:
115: /* }}} */
116:
117: /* {{{ proto string sha1_file(string filename [, bool raw_output])
118: Calculate the sha1 hash of given filename */
119: PHP_FUNCTION(sha1_file)
120: {
121: char *arg;
122: int arg_len;
123: zend_bool raw_output = 0;
124: char sha1str[41];
125: unsigned char buf[1024];
126: unsigned char digest[20];
127: PHP_SHA1_CTX context;
128: int n;
129: php_stream *stream;
130:
1.1.1.2 misho 131: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
1.1 misho 132: return;
133: }
134:
1.1.1.2 misho 135: stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, NULL);
1.1 misho 136: if (!stream) {
137: RETURN_FALSE;
138: }
139:
140: PHP_SHA1Init(&context);
141:
142: while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
143: PHP_SHA1Update(&context, buf, n);
144: }
145:
146: PHP_SHA1Final(digest, &context);
147:
148: php_stream_close(stream);
149:
150: if (n<0) {
151: RETURN_FALSE;
152: }
153:
154: if (raw_output) {
155: RETURN_STRINGL(digest, 20, 1);
156: } else {
157: make_sha1_digest(sha1str, digest);
158: RETVAL_STRING(sha1str, 1);
159: }
160: }
161: /* }}} */
162:
163: /* F, G, H and I are basic SHA1 functions.
164: */
165: #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
166: #define G(x, y, z) ((x) ^ (y) ^ (z))
167: #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
168: #define I(x, y, z) ((x) ^ (y) ^ (z))
169:
170: /* ROTATE_LEFT rotates x left n bits.
171: */
172: #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
173:
174: /* W[i]
175: */
176: #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
177: (x[i&15]=ROTATE_LEFT(tmp, 1)) )
178:
179: /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
180: */
181: #define FF(a, b, c, d, e, w) { \
182: (e) += F ((b), (c), (d)) + (w) + (php_hash_uint32)(0x5A827999); \
183: (e) += ROTATE_LEFT ((a), 5); \
184: (b) = ROTATE_LEFT((b), 30); \
185: }
186: #define GG(a, b, c, d, e, w) { \
187: (e) += G ((b), (c), (d)) + (w) + (php_hash_uint32)(0x6ED9EBA1); \
188: (e) += ROTATE_LEFT ((a), 5); \
189: (b) = ROTATE_LEFT((b), 30); \
190: }
191: #define HH(a, b, c, d, e, w) { \
192: (e) += H ((b), (c), (d)) + (w) + (php_hash_uint32)(0x8F1BBCDC); \
193: (e) += ROTATE_LEFT ((a), 5); \
194: (b) = ROTATE_LEFT((b), 30); \
195: }
196: #define II(a, b, c, d, e, w) { \
197: (e) += I ((b), (c), (d)) + (w) + (php_hash_uint32)(0xCA62C1D6); \
198: (e) += ROTATE_LEFT ((a), 5); \
199: (b) = ROTATE_LEFT((b), 30); \
200: }
201:
202:
203: /* {{{ PHP_SHA1Init
204: * SHA1 initialization. Begins an SHA1 operation, writing a new context.
205: */
206: PHP_HASH_API void PHP_SHA1Init(PHP_SHA1_CTX * context)
207: {
208: context->count[0] = context->count[1] = 0;
209: /* Load magic initialization constants.
210: */
211: context->state[0] = 0x67452301;
212: context->state[1] = 0xefcdab89;
213: context->state[2] = 0x98badcfe;
214: context->state[3] = 0x10325476;
215: context->state[4] = 0xc3d2e1f0;
216: }
217: /* }}} */
218:
219: /* {{{ SHA1Transform
220: * SHA1 basic transformation. Transforms state based on block.
221: */
222: static void SHA1Transform(php_hash_uint32 state[5], const unsigned char block[64])
223: {
224: php_hash_uint32 a = state[0], b = state[1], c = state[2];
225: php_hash_uint32 d = state[3], e = state[4], x[16], tmp;
226:
227: SHADecode32(x, block, 64);
228:
229: /* Round 1 */
230: FF(a, b, c, d, e, x[0]); /* 1 */
231: FF(e, a, b, c, d, x[1]); /* 2 */
232: FF(d, e, a, b, c, x[2]); /* 3 */
233: FF(c, d, e, a, b, x[3]); /* 4 */
234: FF(b, c, d, e, a, x[4]); /* 5 */
235: FF(a, b, c, d, e, x[5]); /* 6 */
236: FF(e, a, b, c, d, x[6]); /* 7 */
237: FF(d, e, a, b, c, x[7]); /* 8 */
238: FF(c, d, e, a, b, x[8]); /* 9 */
239: FF(b, c, d, e, a, x[9]); /* 10 */
240: FF(a, b, c, d, e, x[10]); /* 11 */
241: FF(e, a, b, c, d, x[11]); /* 12 */
242: FF(d, e, a, b, c, x[12]); /* 13 */
243: FF(c, d, e, a, b, x[13]); /* 14 */
244: FF(b, c, d, e, a, x[14]); /* 15 */
245: FF(a, b, c, d, e, x[15]); /* 16 */
246: FF(e, a, b, c, d, W(16)); /* 17 */
247: FF(d, e, a, b, c, W(17)); /* 18 */
248: FF(c, d, e, a, b, W(18)); /* 19 */
249: FF(b, c, d, e, a, W(19)); /* 20 */
250:
251: /* Round 2 */
252: GG(a, b, c, d, e, W(20)); /* 21 */
253: GG(e, a, b, c, d, W(21)); /* 22 */
254: GG(d, e, a, b, c, W(22)); /* 23 */
255: GG(c, d, e, a, b, W(23)); /* 24 */
256: GG(b, c, d, e, a, W(24)); /* 25 */
257: GG(a, b, c, d, e, W(25)); /* 26 */
258: GG(e, a, b, c, d, W(26)); /* 27 */
259: GG(d, e, a, b, c, W(27)); /* 28 */
260: GG(c, d, e, a, b, W(28)); /* 29 */
261: GG(b, c, d, e, a, W(29)); /* 30 */
262: GG(a, b, c, d, e, W(30)); /* 31 */
263: GG(e, a, b, c, d, W(31)); /* 32 */
264: GG(d, e, a, b, c, W(32)); /* 33 */
265: GG(c, d, e, a, b, W(33)); /* 34 */
266: GG(b, c, d, e, a, W(34)); /* 35 */
267: GG(a, b, c, d, e, W(35)); /* 36 */
268: GG(e, a, b, c, d, W(36)); /* 37 */
269: GG(d, e, a, b, c, W(37)); /* 38 */
270: GG(c, d, e, a, b, W(38)); /* 39 */
271: GG(b, c, d, e, a, W(39)); /* 40 */
272:
273: /* Round 3 */
274: HH(a, b, c, d, e, W(40)); /* 41 */
275: HH(e, a, b, c, d, W(41)); /* 42 */
276: HH(d, e, a, b, c, W(42)); /* 43 */
277: HH(c, d, e, a, b, W(43)); /* 44 */
278: HH(b, c, d, e, a, W(44)); /* 45 */
279: HH(a, b, c, d, e, W(45)); /* 46 */
280: HH(e, a, b, c, d, W(46)); /* 47 */
281: HH(d, e, a, b, c, W(47)); /* 48 */
282: HH(c, d, e, a, b, W(48)); /* 49 */
283: HH(b, c, d, e, a, W(49)); /* 50 */
284: HH(a, b, c, d, e, W(50)); /* 51 */
285: HH(e, a, b, c, d, W(51)); /* 52 */
286: HH(d, e, a, b, c, W(52)); /* 53 */
287: HH(c, d, e, a, b, W(53)); /* 54 */
288: HH(b, c, d, e, a, W(54)); /* 55 */
289: HH(a, b, c, d, e, W(55)); /* 56 */
290: HH(e, a, b, c, d, W(56)); /* 57 */
291: HH(d, e, a, b, c, W(57)); /* 58 */
292: HH(c, d, e, a, b, W(58)); /* 59 */
293: HH(b, c, d, e, a, W(59)); /* 60 */
294:
295: /* Round 4 */
296: II(a, b, c, d, e, W(60)); /* 61 */
297: II(e, a, b, c, d, W(61)); /* 62 */
298: II(d, e, a, b, c, W(62)); /* 63 */
299: II(c, d, e, a, b, W(63)); /* 64 */
300: II(b, c, d, e, a, W(64)); /* 65 */
301: II(a, b, c, d, e, W(65)); /* 66 */
302: II(e, a, b, c, d, W(66)); /* 67 */
303: II(d, e, a, b, c, W(67)); /* 68 */
304: II(c, d, e, a, b, W(68)); /* 69 */
305: II(b, c, d, e, a, W(69)); /* 70 */
306: II(a, b, c, d, e, W(70)); /* 71 */
307: II(e, a, b, c, d, W(71)); /* 72 */
308: II(d, e, a, b, c, W(72)); /* 73 */
309: II(c, d, e, a, b, W(73)); /* 74 */
310: II(b, c, d, e, a, W(74)); /* 75 */
311: II(a, b, c, d, e, W(75)); /* 76 */
312: II(e, a, b, c, d, W(76)); /* 77 */
313: II(d, e, a, b, c, W(77)); /* 78 */
314: II(c, d, e, a, b, W(78)); /* 79 */
315: II(b, c, d, e, a, W(79)); /* 80 */
316:
317: state[0] += a;
318: state[1] += b;
319: state[2] += c;
320: state[3] += d;
321: state[4] += e;
322:
323: /* Zeroize sensitive information. */
324: memset((unsigned char*) x, 0, sizeof(x));
325: }
326: /* }}} */
327:
328: /* {{{ PHP_SHA1Update
329: SHA1 block update operation. Continues an SHA1 message-digest
330: operation, processing another message block, and updating the
331: context.
332: */
333: PHP_HASH_API void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
334: unsigned int inputLen)
335: {
336: unsigned int i, index, partLen;
337:
338: /* Compute number of bytes mod 64 */
339: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
340:
341: /* Update number of bits */
342: if ((context->count[0] += ((php_hash_uint32) inputLen << 3))
343: < ((php_hash_uint32) inputLen << 3))
344: context->count[1]++;
345: context->count[1] += ((php_hash_uint32) inputLen >> 29);
346:
347: partLen = 64 - index;
348:
349: /* Transform as many times as possible.
350: */
351: if (inputLen >= partLen) {
352: memcpy
353: ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
354: SHA1Transform(context->state, context->buffer);
355:
356: for (i = partLen; i + 63 < inputLen; i += 64)
357: SHA1Transform(context->state, &input[i]);
358:
359: index = 0;
360: } else
361: i = 0;
362:
363: /* Buffer remaining input */
364: memcpy
365: ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
366: inputLen - i);
367: }
368: /* }}} */
369:
370: /* {{{ PHP_SHA1Final
371: SHA1 finalization. Ends an SHA1 message-digest operation, writing the
372: the message digest and zeroizing the context.
373: */
374: PHP_HASH_API void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
375: {
376: unsigned char bits[8];
377: unsigned int index, padLen;
378:
379: /* Save number of bits */
380: bits[7] = context->count[0] & 0xFF;
381: bits[6] = (context->count[0] >> 8) & 0xFF;
382: bits[5] = (context->count[0] >> 16) & 0xFF;
383: bits[4] = (context->count[0] >> 24) & 0xFF;
384: bits[3] = context->count[1] & 0xFF;
385: bits[2] = (context->count[1] >> 8) & 0xFF;
386: bits[1] = (context->count[1] >> 16) & 0xFF;
387: bits[0] = (context->count[1] >> 24) & 0xFF;
388:
389: /* Pad out to 56 mod 64.
390: */
391: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
392: padLen = (index < 56) ? (56 - index) : (120 - index);
393: PHP_SHA1Update(context, PADDING, padLen);
394:
395: /* Append length (before padding) */
396: PHP_SHA1Update(context, bits, 8);
397:
398: /* Store state in digest */
399: SHAEncode32(digest, context->state, 20);
400:
401: /* Zeroize sensitive information.
402: */
403: memset((unsigned char*) context, 0, sizeof(*context));
404: }
405: /* }}} */
406:
407: #endif /* PHP_HASH_SHA1_NOT_IN_CORE */
408:
409: /* sha224/sha256 */
410:
411: const php_hash_ops php_hash_sha256_ops = {
412: (php_hash_init_func_t) PHP_SHA256Init,
413: (php_hash_update_func_t) PHP_SHA256Update,
414: (php_hash_final_func_t) PHP_SHA256Final,
415: (php_hash_copy_func_t) php_hash_copy,
416: 32,
417: 64,
418: sizeof(PHP_SHA256_CTX)
419: };
420:
421: const php_hash_ops php_hash_sha224_ops = {
422: (php_hash_init_func_t) PHP_SHA224Init,
423: (php_hash_update_func_t) PHP_SHA224Update,
424: (php_hash_final_func_t) PHP_SHA224Final,
425: (php_hash_copy_func_t) php_hash_copy,
426: 28,
427: 64,
428: sizeof(PHP_SHA224_CTX)
429: };
430:
431: #define ROTR32(b,x) ((x >> b) | (x << (32 - b)))
432: #define ROTR64(b,x) ((x >> b) | (x << (64 - b)))
433: #define SHR(b, x) (x >> b)
434:
435: /* Ch */
436: #define SHA256_F0(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
437: /* Maj */
438: #define SHA256_F1(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
439: /* SUM0 */
440: #define SHA256_F2(x) (ROTR32( 2,(x)) ^ ROTR32(13,(x)) ^ ROTR32(22,(x)))
441: /* SUM1 */
442: #define SHA256_F3(x) (ROTR32( 6,(x)) ^ ROTR32(11,(x)) ^ ROTR32(25,(x)))
443: /* OM0 */
444: #define SHA256_F4(x) (ROTR32( 7,(x)) ^ ROTR32(18,(x)) ^ SHR( 3,(x)))
445: /* OM1 */
446: #define SHA256_F5(x) (ROTR32(17,(x)) ^ ROTR32(19,(x)) ^ SHR(10,(x)))
447:
448: static const php_hash_uint32 SHA256_K[64] = {
449: 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
450: 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
451: 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
452: 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
453: 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
454: 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
455: 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
456: 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
457:
458: /* {{{ PHP_SHA256Init
459: * SHA256 initialization. Begins an SHA256 operation, writing a new context.
460: */
461: PHP_HASH_API void PHP_SHA256Init(PHP_SHA256_CTX * context)
462: {
463: context->count[0] = context->count[1] = 0;
464: /* Load magic initialization constants.
465: */
466: context->state[0] = 0x6a09e667;
467: context->state[1] = 0xbb67ae85;
468: context->state[2] = 0x3c6ef372;
469: context->state[3] = 0xa54ff53a;
470: context->state[4] = 0x510e527f;
471: context->state[5] = 0x9b05688c;
472: context->state[6] = 0x1f83d9ab;
473: context->state[7] = 0x5be0cd19;
474: }
475: /* }}} */
476:
477: /* {{{ SHA256Transform
478: * SHA256 basic transformation. Transforms state based on block.
479: */
480: static void SHA256Transform(php_hash_uint32 state[8], const unsigned char block[64])
481: {
482: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
483: php_hash_uint32 e = state[4], f = state[5], g = state[6], h = state[7];
484: php_hash_uint32 x[16], T1, T2, W[64];
485: int i;
486:
487: SHADecode32(x, block, 64);
488:
489: /* Schedule */
490: for(i = 0; i < 16; i++) {
491: W[i] = x[i];
492: }
493: for(i = 16; i < 64; i++) {
494: W[i] = SHA256_F5(W[i-2]) + W[i-7] + SHA256_F4(W[i-15]) + W[i-16];
495: }
496:
497: for (i = 0; i < 64; i++) {
498: T1 = h + SHA256_F3(e) + SHA256_F0(e,f,g) + SHA256_K[i] + W[i];
499: T2 = SHA256_F2(a) + SHA256_F1(a,b,c);
500: h = g; g = f; f = e; e = d + T1;
501: d = c; c = b; b = a; a = T1 + T2;
502: }
503:
504: state[0] += a;
505: state[1] += b;
506: state[2] += c;
507: state[3] += d;
508: state[4] += e;
509: state[5] += f;
510: state[6] += g;
511: state[7] += h;
512:
513: /* Zeroize sensitive information. */
514: memset((unsigned char*) x, 0, sizeof(x));
515: }
516: /* }}} */
517:
518: /* {{{ PHP_SHA224Init
519: * SHA224 initialization. Begins an SHA224 operation, writing a new context.
520: */
521: PHP_HASH_API void PHP_SHA224Init(PHP_SHA224_CTX * context)
522: {
523: context->count[0] = context->count[1] = 0;
524: /* Load magic initialization constants.
525: */
526: context->state[0] = 0xc1059ed8;
527: context->state[1] = 0x367cd507;
528: context->state[2] = 0x3070dd17;
529: context->state[3] = 0xf70e5939;
530: context->state[4] = 0xffc00b31;
531: context->state[5] = 0x68581511;
532: context->state[6] = 0x64f98fa7;
533: context->state[7] = 0xbefa4fa4;
534: }
535: /* }}} */
536:
537: /* {{{ PHP_SHA224Update
538: SHA224 block update operation. Continues an SHA224 message-digest
539: operation, processing another message block, and updating the
540: context.
541: */
542: PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX * context, const unsigned char *input, unsigned int inputLen)
543: {
544: unsigned int i, index, partLen;
545:
546: /* Compute number of bytes mod 64 */
547: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
548:
549: /* Update number of bits */
550: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
551: context->count[1]++;
552: }
553: context->count[1] += ((php_hash_uint32) inputLen >> 29);
554:
555: partLen = 64 - index;
556:
557: /* Transform as many times as possible.
558: */
559: if (inputLen >= partLen) {
560: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
561: SHA256Transform(context->state, context->buffer);
562:
563: for (i = partLen; i + 63 < inputLen; i += 64) {
564: SHA256Transform(context->state, &input[i]);
565: }
566:
567: index = 0;
568: } else {
569: i = 0;
570: }
571:
572: /* Buffer remaining input */
573: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
574: }
575: /* }}} */
576:
577: /* {{{ PHP_SHA224Final
578: SHA224 finalization. Ends an SHA224 message-digest operation, writing the
579: the message digest and zeroizing the context.
580: */
581: PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context)
582: {
583: unsigned char bits[8];
584: unsigned int index, padLen;
585:
586: /* Save number of bits */
587: bits[7] = (unsigned char) (context->count[0] & 0xFF);
588: bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
589: bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
590: bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
591: bits[3] = (unsigned char) (context->count[1] & 0xFF);
592: bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
593: bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
594: bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
595:
596: /* Pad out to 56 mod 64.
597: */
598: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
599: padLen = (index < 56) ? (56 - index) : (120 - index);
600: PHP_SHA224Update(context, PADDING, padLen);
601:
602: /* Append length (before padding) */
603: PHP_SHA224Update(context, bits, 8);
604:
605: /* Store state in digest */
606: SHAEncode32(digest, context->state, 28);
607:
608: /* Zeroize sensitive information.
609: */
610: memset((unsigned char*) context, 0, sizeof(*context));
611: }
612: /* }}} */
613:
614: /* {{{ PHP_SHA256Update
615: SHA256 block update operation. Continues an SHA256 message-digest
616: operation, processing another message block, and updating the
617: context.
618: */
619: PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, unsigned int inputLen)
620: {
621: unsigned int i, index, partLen;
622:
623: /* Compute number of bytes mod 64 */
624: index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
625:
626: /* Update number of bits */
627: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
628: context->count[1]++;
629: }
630: context->count[1] += ((php_hash_uint32) inputLen >> 29);
631:
632: partLen = 64 - index;
633:
634: /* Transform as many times as possible.
635: */
636: if (inputLen >= partLen) {
637: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
638: SHA256Transform(context->state, context->buffer);
639:
640: for (i = partLen; i + 63 < inputLen; i += 64) {
641: SHA256Transform(context->state, &input[i]);
642: }
643:
644: index = 0;
645: } else {
646: i = 0;
647: }
648:
649: /* Buffer remaining input */
650: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
651: }
652: /* }}} */
653:
654: /* {{{ PHP_SHA256Final
655: SHA256 finalization. Ends an SHA256 message-digest operation, writing the
656: the message digest and zeroizing the context.
657: */
658: PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
659: {
660: unsigned char bits[8];
661: unsigned int index, padLen;
662:
663: /* Save number of bits */
664: bits[7] = (unsigned char) (context->count[0] & 0xFF);
665: bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
666: bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
667: bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
668: bits[3] = (unsigned char) (context->count[1] & 0xFF);
669: bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
670: bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
671: bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
672:
673: /* Pad out to 56 mod 64.
674: */
675: index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
676: padLen = (index < 56) ? (56 - index) : (120 - index);
677: PHP_SHA256Update(context, PADDING, padLen);
678:
679: /* Append length (before padding) */
680: PHP_SHA256Update(context, bits, 8);
681:
682: /* Store state in digest */
683: SHAEncode32(digest, context->state, 32);
684:
685: /* Zeroize sensitive information.
686: */
687: memset((unsigned char*) context, 0, sizeof(*context));
688: }
689: /* }}} */
690:
691: /* sha384/sha512 */
692:
693: /* Ch */
694: #define SHA512_F0(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
695: /* Maj */
696: #define SHA512_F1(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
697: /* SUM0 */
698: #define SHA512_F2(x) (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
699: /* SUM1 */
700: #define SHA512_F3(x) (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
701: /* OM0 */
702: #define SHA512_F4(x) (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
703: /* OM1 */
704: #define SHA512_F5(x) (ROTR64(19, x) ^ ROTR64(61, x) ^ SHR(6, x))
705:
706: static const php_hash_uint64 SHA512_K[128] = {
707: L64(0x428a2f98d728ae22), L64(0x7137449123ef65cd), L64(0xb5c0fbcfec4d3b2f), L64(0xe9b5dba58189dbbc),
708: L64(0x3956c25bf348b538), L64(0x59f111f1b605d019), L64(0x923f82a4af194f9b), L64(0xab1c5ed5da6d8118),
709: L64(0xd807aa98a3030242), L64(0x12835b0145706fbe), L64(0x243185be4ee4b28c), L64(0x550c7dc3d5ffb4e2),
710: L64(0x72be5d74f27b896f), L64(0x80deb1fe3b1696b1), L64(0x9bdc06a725c71235), L64(0xc19bf174cf692694),
711: L64(0xe49b69c19ef14ad2), L64(0xefbe4786384f25e3), L64(0x0fc19dc68b8cd5b5), L64(0x240ca1cc77ac9c65),
712: L64(0x2de92c6f592b0275), L64(0x4a7484aa6ea6e483), L64(0x5cb0a9dcbd41fbd4), L64(0x76f988da831153b5),
713: L64(0x983e5152ee66dfab), L64(0xa831c66d2db43210), L64(0xb00327c898fb213f), L64(0xbf597fc7beef0ee4),
714: L64(0xc6e00bf33da88fc2), L64(0xd5a79147930aa725), L64(0x06ca6351e003826f), L64(0x142929670a0e6e70),
715: L64(0x27b70a8546d22ffc), L64(0x2e1b21385c26c926), L64(0x4d2c6dfc5ac42aed), L64(0x53380d139d95b3df),
716: L64(0x650a73548baf63de), L64(0x766a0abb3c77b2a8), L64(0x81c2c92e47edaee6), L64(0x92722c851482353b),
717: L64(0xa2bfe8a14cf10364), L64(0xa81a664bbc423001), L64(0xc24b8b70d0f89791), L64(0xc76c51a30654be30),
718: L64(0xd192e819d6ef5218), L64(0xd69906245565a910), L64(0xf40e35855771202a), L64(0x106aa07032bbd1b8),
719: L64(0x19a4c116b8d2d0c8), L64(0x1e376c085141ab53), L64(0x2748774cdf8eeb99), L64(0x34b0bcb5e19b48a8),
720: L64(0x391c0cb3c5c95a63), L64(0x4ed8aa4ae3418acb), L64(0x5b9cca4f7763e373), L64(0x682e6ff3d6b2b8a3),
721: L64(0x748f82ee5defb2fc), L64(0x78a5636f43172f60), L64(0x84c87814a1f0ab72), L64(0x8cc702081a6439ec),
722: L64(0x90befffa23631e28), L64(0xa4506cebde82bde9), L64(0xbef9a3f7b2c67915), L64(0xc67178f2e372532b),
723: L64(0xca273eceea26619c), L64(0xd186b8c721c0c207), L64(0xeada7dd6cde0eb1e), L64(0xf57d4f7fee6ed178),
724: L64(0x06f067aa72176fba), L64(0x0a637dc5a2c898a6), L64(0x113f9804bef90dae), L64(0x1b710b35131c471b),
725: L64(0x28db77f523047d84), L64(0x32caab7b40c72493), L64(0x3c9ebe0a15c9bebc), L64(0x431d67c49c100d4c),
726: L64(0x4cc5d4becb3e42b6), L64(0x597f299cfc657e2a), L64(0x5fcb6fab3ad6faec), L64(0x6c44198c4a475817) };
727:
728: /* {{{ SHAEncode64
729: Encodes input (php_hash_uint64) into output (unsigned char). Assumes len is
730: a multiple of 8.
731: */
732: static void SHAEncode64(unsigned char *output, php_hash_uint64 *input, unsigned int len)
733: {
734: unsigned int i, j;
735:
736: for (i = 0, j = 0; j < len; i++, j += 8) {
737: output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
738: output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
739: output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
740: output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
741: output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
742: output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
743: output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
744: output[j + 7] = (unsigned char) (input[i] & 0xff);
745: }
746: }
747: /* }}} */
748:
749:
750: /* {{{ SHADecode64
751: Decodes input (unsigned char) into output (php_hash_uint64). Assumes len is
752: a multiple of 8.
753: */
754: static void SHADecode64(php_hash_uint64 *output, const unsigned char *input, unsigned int len)
755: {
756: unsigned int i, j;
757:
758: for (i = 0, j = 0; j < len; i++, j += 8)
759: output[i] =
760: ((php_hash_uint64) input[j + 7]) | (((php_hash_uint64) input[j + 6]) << 8) |
761: (((php_hash_uint64) input[j + 5]) << 16) | (((php_hash_uint64) input[j + 4]) << 24) |
762: (((php_hash_uint64) input[j + 3]) << 32) | (((php_hash_uint64) input[j + 2]) << 40) |
763: (((php_hash_uint64) input[j + 1]) << 48) | (((php_hash_uint64) input[j]) << 56);
764: }
765: /* }}} */
766:
767: /* {{{ PHP_SHA384Init
768: * SHA384 initialization. Begins an SHA384 operation, writing a new context.
769: */
770: PHP_HASH_API void PHP_SHA384Init(PHP_SHA384_CTX * context)
771: {
772: context->count[0] = context->count[1] = 0;
773: /* Load magic initialization constants.
774: */
775: context->state[0] = L64(0xcbbb9d5dc1059ed8);
776: context->state[1] = L64(0x629a292a367cd507);
777: context->state[2] = L64(0x9159015a3070dd17);
778: context->state[3] = L64(0x152fecd8f70e5939);
779: context->state[4] = L64(0x67332667ffc00b31);
780: context->state[5] = L64(0x8eb44a8768581511);
781: context->state[6] = L64(0xdb0c2e0d64f98fa7);
782: context->state[7] = L64(0x47b5481dbefa4fa4);
783: }
784: /* }}} */
785:
786: /* {{{ SHA512Transform
787: * SHA512 basic transformation. Transforms state based on block.
788: * SHA384 uses the exact same algorithm
789: */
790: static void SHA512Transform(php_hash_uint64 state[8], const unsigned char block[128])
791: {
792: php_hash_uint64 a = state[0], b = state[1], c = state[2], d = state[3];
793: php_hash_uint64 e = state[4], f = state[5], g = state[6], h = state[7];
794: php_hash_uint64 x[16], T1, T2, W[80];
795: int i;
796:
797: SHADecode64(x, block, 128);
798:
799: /* Schedule */
800: for(i = 0; i < 16; i++) {
801: W[i] = x[i];
802: }
803: for(i = 16; i < 80; i++) {
804: W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
805: }
806:
807: for (i = 0; i < 80; i++) {
808: T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
809: T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
810: h = g; g = f; f = e; e = d + T1;
811: d = c; c = b; b = a; a = T1 + T2;
812: }
813:
814: state[0] += a;
815: state[1] += b;
816: state[2] += c;
817: state[3] += d;
818: state[4] += e;
819: state[5] += f;
820: state[6] += g;
821: state[7] += h;
822:
823: /* Zeroize sensitive information. */
824: memset((unsigned char*) x, 0, sizeof(x));
825: }
826: /* }}} */
827:
828: /* {{{ PHP_SHA384Update
829: SHA384 block update operation. Continues an SHA384 message-digest
830: operation, processing another message block, and updating the
831: context.
832: */
833: PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX * context, const unsigned char *input, unsigned int inputLen)
834: {
835: unsigned int i, index, partLen;
836:
837: /* Compute number of bytes mod 128 */
838: index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
839:
840: /* Update number of bits */
841: if ((context->count[0] += ((php_hash_uint64) inputLen << 3)) < ((php_hash_uint64) inputLen << 3)) {
842: context->count[1]++;
843: }
844: context->count[1] += ((php_hash_uint64) inputLen >> 61);
845:
846: partLen = 128 - index;
847:
848: /* Transform as many times as possible.
849: */
850: if (inputLen >= partLen) {
851: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
852: SHA512Transform(context->state, context->buffer);
853:
854: for (i = partLen; i + 127 < inputLen; i += 128) {
855: SHA512Transform(context->state, &input[i]);
856: }
857:
858: index = 0;
859: } else {
860: i = 0;
861: }
862:
863: /* Buffer remaining input */
864: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
865: }
866: /* }}} */
867:
868: /* {{{ PHP_SHA384Final
869: SHA384 finalization. Ends an SHA384 message-digest operation, writing the
870: the message digest and zeroizing the context.
871: */
872: PHP_HASH_API void PHP_SHA384Final(unsigned char digest[48], PHP_SHA384_CTX * context)
873: {
874: unsigned char bits[16];
875: unsigned int index, padLen;
876:
877: /* Save number of bits */
878: bits[15] = (unsigned char) (context->count[0] & 0xFF);
879: bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
880: bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
881: bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
882: bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
883: bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
884: bits[9] = (unsigned char) ((context->count[0] >> 48) & 0xFF);
885: bits[8] = (unsigned char) ((context->count[0] >> 56) & 0xFF);
886: bits[7] = (unsigned char) (context->count[1] & 0xFF);
887: bits[6] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
888: bits[5] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
889: bits[4] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
890: bits[3] = (unsigned char) ((context->count[1] >> 32) & 0xFF);
891: bits[2] = (unsigned char) ((context->count[1] >> 40) & 0xFF);
892: bits[1] = (unsigned char) ((context->count[1] >> 48) & 0xFF);
893: bits[0] = (unsigned char) ((context->count[1] >> 56) & 0xFF);
894:
895: /* Pad out to 112 mod 128.
896: */
897: index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
898: padLen = (index < 112) ? (112 - index) : (240 - index);
899: PHP_SHA384Update(context, PADDING, padLen);
900:
901: /* Append length (before padding) */
902: PHP_SHA384Update(context, bits, 16);
903:
904: /* Store state in digest */
905: SHAEncode64(digest, context->state, 48);
906:
907: /* Zeroize sensitive information.
908: */
909: memset((unsigned char*) context, 0, sizeof(*context));
910: }
911: /* }}} */
912:
913: const php_hash_ops php_hash_sha384_ops = {
914: (php_hash_init_func_t) PHP_SHA384Init,
915: (php_hash_update_func_t) PHP_SHA384Update,
916: (php_hash_final_func_t) PHP_SHA384Final,
917: (php_hash_copy_func_t) php_hash_copy,
918: 48,
919: 128,
920: sizeof(PHP_SHA384_CTX)
921: };
922:
923: /* {{{ PHP_SHA512Init
924: * SHA512 initialization. Begins an SHA512 operation, writing a new context.
925: */
926: PHP_HASH_API void PHP_SHA512Init(PHP_SHA512_CTX * context)
927: {
928: context->count[0] = context->count[1] = 0;
929: /* Load magic initialization constants.
930: */
931: context->state[0] = L64(0x6a09e667f3bcc908);
932: context->state[1] = L64(0xbb67ae8584caa73b);
933: context->state[2] = L64(0x3c6ef372fe94f82b);
934: context->state[3] = L64(0xa54ff53a5f1d36f1);
935: context->state[4] = L64(0x510e527fade682d1);
936: context->state[5] = L64(0x9b05688c2b3e6c1f);
937: context->state[6] = L64(0x1f83d9abfb41bd6b);
938: context->state[7] = L64(0x5be0cd19137e2179);
939: }
940: /* }}} */
941:
942: /* {{{ PHP_SHA512Update
943: SHA512 block update operation. Continues an SHA512 message-digest
944: operation, processing another message block, and updating the
945: context.
946: */
947: PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char *input, unsigned int inputLen)
948: {
949: unsigned int i, index, partLen;
950:
951: /* Compute number of bytes mod 128 */
952: index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
953:
954: /* Update number of bits */
955: if ((context->count[0] += ((php_hash_uint64) inputLen << 3)) < ((php_hash_uint64) inputLen << 3)) {
956: context->count[1]++;
957: }
958: context->count[1] += ((php_hash_uint64) inputLen >> 61);
959:
960: partLen = 128 - index;
961:
962: /* Transform as many times as possible.
963: */
964: if (inputLen >= partLen) {
965: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
966: SHA512Transform(context->state, context->buffer);
967:
968: for (i = partLen; i + 127 < inputLen; i += 128) {
969: SHA512Transform(context->state, &input[i]);
970: }
971:
972: index = 0;
973: } else {
974: i = 0;
975: }
976:
977: /* Buffer remaining input */
978: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
979: }
980: /* }}} */
981:
982: /* {{{ PHP_SHA512Final
983: SHA512 finalization. Ends an SHA512 message-digest operation, writing the
984: the message digest and zeroizing the context.
985: */
986: PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context)
987: {
988: unsigned char bits[16];
989: unsigned int index, padLen;
990:
991: /* Save number of bits */
992: bits[15] = (unsigned char) (context->count[0] & 0xFF);
993: bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
994: bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
995: bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
996: bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
997: bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
998: bits[9] = (unsigned char) ((context->count[0] >> 48) & 0xFF);
999: bits[8] = (unsigned char) ((context->count[0] >> 56) & 0xFF);
1000: bits[7] = (unsigned char) (context->count[1] & 0xFF);
1001: bits[6] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
1002: bits[5] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
1003: bits[4] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
1004: bits[3] = (unsigned char) ((context->count[1] >> 32) & 0xFF);
1005: bits[2] = (unsigned char) ((context->count[1] >> 40) & 0xFF);
1006: bits[1] = (unsigned char) ((context->count[1] >> 48) & 0xFF);
1007: bits[0] = (unsigned char) ((context->count[1] >> 56) & 0xFF);
1008:
1009: /* Pad out to 112 mod 128.
1010: */
1011: index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
1012: padLen = (index < 112) ? (112 - index) : (240 - index);
1013: PHP_SHA512Update(context, PADDING, padLen);
1014:
1015: /* Append length (before padding) */
1016: PHP_SHA512Update(context, bits, 16);
1017:
1018: /* Store state in digest */
1019: SHAEncode64(digest, context->state, 64);
1020:
1021: /* Zeroize sensitive information.
1022: */
1023: memset((unsigned char*) context, 0, sizeof(*context));
1024: }
1025: /* }}} */
1026:
1027: const php_hash_ops php_hash_sha512_ops = {
1028: (php_hash_init_func_t) PHP_SHA512Init,
1029: (php_hash_update_func_t) PHP_SHA512Update,
1030: (php_hash_final_func_t) PHP_SHA512Final,
1031: (php_hash_copy_func_t) php_hash_copy,
1032: 64,
1033: 128,
1034: sizeof(PHP_SHA512_CTX)
1035: };
1036:
1037: /*
1038: * Local variables:
1039: * tab-width: 4
1040: * c-basic-offset: 4
1041: * End:
1042: * vim600: sw=4 ts=4 fdm=marker
1043: * vim<600: sw=4 ts=4
1044: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>