1*0a6a1f1dSLionel Sambuc /* $NetBSD: crc.c,v 1.19 2014/10/29 18:09:35 uebayasi Exp $ */
2280d8c66SLionel Sambuc
3280d8c66SLionel Sambuc /*-
4280d8c66SLionel Sambuc * Copyright (c) 1991, 1993
5280d8c66SLionel Sambuc * The Regents of the University of California. All rights reserved.
6280d8c66SLionel Sambuc *
7280d8c66SLionel Sambuc * This code is derived from software contributed to Berkeley by
8280d8c66SLionel Sambuc * James W. Williams of NASA Goddard Space Flight Center.
9280d8c66SLionel Sambuc *
10280d8c66SLionel Sambuc * Redistribution and use in source and binary forms, with or without
11280d8c66SLionel Sambuc * modification, are permitted provided that the following conditions
12280d8c66SLionel Sambuc * are met:
13280d8c66SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
14280d8c66SLionel Sambuc * notice, this list of conditions and the following disclaimer.
15280d8c66SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16280d8c66SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
17280d8c66SLionel Sambuc * documentation and/or other materials provided with the distribution.
18280d8c66SLionel Sambuc * 3. Neither the name of the University nor the names of its contributors
19280d8c66SLionel Sambuc * may be used to endorse or promote products derived from this software
20280d8c66SLionel Sambuc * without specific prior written permission.
21280d8c66SLionel Sambuc *
22280d8c66SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23280d8c66SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24280d8c66SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25280d8c66SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26280d8c66SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27280d8c66SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28280d8c66SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29280d8c66SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30280d8c66SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31280d8c66SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32280d8c66SLionel Sambuc * SUCH DAMAGE.
33280d8c66SLionel Sambuc */
34280d8c66SLionel Sambuc
35280d8c66SLionel Sambuc #if HAVE_NBTOOL_CONFIG_H
36280d8c66SLionel Sambuc #include "nbtool_config.h"
37280d8c66SLionel Sambuc #endif
38280d8c66SLionel Sambuc
39280d8c66SLionel Sambuc #include <sys/cdefs.h>
40280d8c66SLionel Sambuc #if defined(__RCSID) && !defined(lint)
41280d8c66SLionel Sambuc #if 0
42280d8c66SLionel Sambuc static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 6/17/93";
43280d8c66SLionel Sambuc #else
44*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: crc.c,v 1.19 2014/10/29 18:09:35 uebayasi Exp $");
45280d8c66SLionel Sambuc #endif
46280d8c66SLionel Sambuc #endif /* not lint */
47280d8c66SLionel Sambuc
48280d8c66SLionel Sambuc #include <sys/types.h>
49280d8c66SLionel Sambuc #include <unistd.h>
50280d8c66SLionel Sambuc
51280d8c66SLionel Sambuc #include "extern.h"
52280d8c66SLionel Sambuc
53280d8c66SLionel Sambuc static const u_int32_t crctab[] = {
54280d8c66SLionel Sambuc 0x0,
55280d8c66SLionel Sambuc 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
56280d8c66SLionel Sambuc 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
57280d8c66SLionel Sambuc 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
58280d8c66SLionel Sambuc 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
59280d8c66SLionel Sambuc 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
60280d8c66SLionel Sambuc 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
61280d8c66SLionel Sambuc 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
62280d8c66SLionel Sambuc 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
63280d8c66SLionel Sambuc 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
64280d8c66SLionel Sambuc 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
65280d8c66SLionel Sambuc 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
66280d8c66SLionel Sambuc 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
67280d8c66SLionel Sambuc 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
68280d8c66SLionel Sambuc 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
69280d8c66SLionel Sambuc 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
70280d8c66SLionel Sambuc 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
71280d8c66SLionel Sambuc 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
72280d8c66SLionel Sambuc 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
73280d8c66SLionel Sambuc 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
74280d8c66SLionel Sambuc 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
75280d8c66SLionel Sambuc 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
76280d8c66SLionel Sambuc 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
77280d8c66SLionel Sambuc 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
78280d8c66SLionel Sambuc 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
79280d8c66SLionel Sambuc 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
80280d8c66SLionel Sambuc 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
81280d8c66SLionel Sambuc 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
82280d8c66SLionel Sambuc 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
83280d8c66SLionel Sambuc 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
84280d8c66SLionel Sambuc 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
85280d8c66SLionel Sambuc 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
86280d8c66SLionel Sambuc 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
87280d8c66SLionel Sambuc 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
88280d8c66SLionel Sambuc 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
89280d8c66SLionel Sambuc 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
90280d8c66SLionel Sambuc 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
91280d8c66SLionel Sambuc 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
92280d8c66SLionel Sambuc 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
93280d8c66SLionel Sambuc 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
94280d8c66SLionel Sambuc 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
95280d8c66SLionel Sambuc 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
96280d8c66SLionel Sambuc 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
97280d8c66SLionel Sambuc 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
98280d8c66SLionel Sambuc 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
99280d8c66SLionel Sambuc 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
100280d8c66SLionel Sambuc 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
101280d8c66SLionel Sambuc 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
102280d8c66SLionel Sambuc 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
103280d8c66SLionel Sambuc 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
104280d8c66SLionel Sambuc 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
105280d8c66SLionel Sambuc 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
106280d8c66SLionel Sambuc };
107280d8c66SLionel Sambuc
108280d8c66SLionel Sambuc /*
109280d8c66SLionel Sambuc * Compute a POSIX 1003.2 checksum. This routine has been broken out so that
110280d8c66SLionel Sambuc * other programs can use it. It takes a file descriptor to read from and
111280d8c66SLionel Sambuc * locations to store the crc and the number of bytes read. It returns 0 on
112280d8c66SLionel Sambuc * success and 1 on failure. Errno is set on failure.
113280d8c66SLionel Sambuc */
114280d8c66SLionel Sambuc int
crc(int fd,u_int32_t * cval,off_t * clen)115280d8c66SLionel Sambuc crc(int fd, u_int32_t *cval, off_t *clen)
116280d8c66SLionel Sambuc {
117280d8c66SLionel Sambuc u_char *p;
118*0a6a1f1dSLionel Sambuc ssize_t nr;
119280d8c66SLionel Sambuc u_int32_t thecrc;
120280d8c66SLionel Sambuc off_t len;
121280d8c66SLionel Sambuc u_char buf[16 * 1024];
122280d8c66SLionel Sambuc
123280d8c66SLionel Sambuc #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
124280d8c66SLionel Sambuc
125280d8c66SLionel Sambuc thecrc = 0;
126280d8c66SLionel Sambuc len = 0;
127280d8c66SLionel Sambuc while ((nr = read(fd, buf, sizeof(buf))) > 0)
128280d8c66SLionel Sambuc for (len += nr, p = buf; nr--; ++p) {
129280d8c66SLionel Sambuc COMPUTE(thecrc, *p);
130280d8c66SLionel Sambuc }
131280d8c66SLionel Sambuc if (nr < 0)
132280d8c66SLionel Sambuc return 1;
133280d8c66SLionel Sambuc
134280d8c66SLionel Sambuc *clen = len;
135280d8c66SLionel Sambuc
136280d8c66SLionel Sambuc /* Include the length of the file. */
137280d8c66SLionel Sambuc for (; len != 0; len >>= 8) {
138280d8c66SLionel Sambuc COMPUTE(thecrc, len & 0xff);
139280d8c66SLionel Sambuc }
140280d8c66SLionel Sambuc
141280d8c66SLionel Sambuc *cval = ~thecrc;
142280d8c66SLionel Sambuc return 0;
143280d8c66SLionel Sambuc }
144280d8c66SLionel Sambuc
145280d8c66SLionel Sambuc /* These two are rather more useful to the outside world */
146280d8c66SLionel Sambuc
147280d8c66SLionel Sambuc uint32_t
crc_buf(uint32_t thecrc,const void * buf,size_t len)148280d8c66SLionel Sambuc crc_buf(uint32_t thecrc, const void *buf, size_t len)
149280d8c66SLionel Sambuc {
150280d8c66SLionel Sambuc const uint8_t *p = buf;
151280d8c66SLionel Sambuc
152280d8c66SLionel Sambuc for (p = buf; len; p++, len--)
153280d8c66SLionel Sambuc COMPUTE(thecrc, *p);
154280d8c66SLionel Sambuc return thecrc;
155280d8c66SLionel Sambuc }
156280d8c66SLionel Sambuc
157280d8c66SLionel Sambuc uint32_t
crc_byte(uint32_t thecrc,unsigned int byte_val)158280d8c66SLionel Sambuc crc_byte(uint32_t thecrc, unsigned int byte_val)
159280d8c66SLionel Sambuc {
160280d8c66SLionel Sambuc COMPUTE(thecrc, byte_val & 0xff);
161280d8c66SLionel Sambuc return thecrc;
162280d8c66SLionel Sambuc }
163