1 /* SCTP kernel reference Implementation
2  * Copyright (c) 1999-2000 Cisco, Inc.
3  * Copyright (c) 1999-2001 Motorola, Inc.
4  * Copyright (c) 2003 International Business Machines, Corp.
5  *
6  * This file is part of the SCTP kernel reference Implementation
7  *
8  * This file has direct heritage from the SCTP user-level reference
9  * implementation by R. Stewart, et al.  These functions implement the
10  * Adler-32 algorithm as specified by RFC 2960.
11  *
12  * The SCTP reference implementation is free software;
13  * you can redistribute it and/or modify it under the terms of
14  * the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * The SCTP reference implementation is distributed in the hope that it
19  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
20  *                 ************************
21  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22  * See the GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with GNU CC; see the file COPYING.  If not, write to
26  * the Free Software Foundation, 59 Temple Place - Suite 330,
27  * Boston, MA 02111-1307, USA.
28  *
29  * Please send any bug reports or fixes you make to the
30  * email address(es):
31  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
32  *
33  * Or submit a bug report through the following website:
34  *    http://www.sf.net/projects/lksctp
35  *
36  * Written or modified by:
37  *    Randall Stewart <rstewar1@email.mot.com>
38  *    Ken Morneau     <kmorneau@cisco.com>
39  *    Qiaobing Xie    <qxie1@email.mot.com>
40  *    Sridhar Samudrala <sri@us.ibm.com>
41  *
42  * Any bugs reported given to us we will try to fix... any fixes shared will
43  * be incorporated into the next SCTP release.
44  */
45 
46 /* This is an entry point for external calls
47  * Define this function in the header file. This is
48  * direct from rfc1950, ...
49  *
50  * The following C code computes the Adler-32 checksum of a data buffer.
51  * It is written for clarity, not for speed.  The sample code is in the
52  * ANSI C programming language. Non C users may find it easier to read
53  * with these hints:
54  *
55  *    &      Bitwise AND operator.
56  *    >>     Bitwise right shift operator. When applied to an
57  *           unsigned quantity, as here, right shift inserts zero bit(s)
58  *           at the left.
59  *    <<     Bitwise left shift operator. Left shift inserts zero
60  *           bit(s) at the right.
61  *    ++     "n++" increments the variable n.
62  *    %      modulo operator: a % b is the remainder of a divided by b.
63  *
64  * Well, the above is a bit of a lie, I have optimized this a small
65  * tad, but I have commented the original lines below
66  */
67 
68 #include <linux/types.h>
69 #include <net/sctp/sctp.h>
70 
71 #define BASE 65521 /* largest prime smaller than 65536 */
72 
73 
74 /* Performance work as shown this pig to be the
75  * worst CPU wise guy. I have done what I could think
76  * of on my flight to Australia but I am sure some
77  * clever assembly could speed this up, but of
78  * course this would require the dreaded #ifdef's for
79  * architecture. If you can speed this up more, pass
80  * it back and we will incorporate it :-)
81  */
82 
update_adler32(unsigned long adler,unsigned char * buf,int len)83 unsigned long update_adler32(unsigned long adler,
84 			     unsigned char *buf, int len)
85 {
86 	__u32 s1 = adler & 0xffff;
87 	__u32 s2 = (adler >> 16) & 0xffff;
88         int n;
89 
90 	for (n = 0; n < len; n++,buf++) {
91 		/* s1 = (s1 + buf[n]) % BASE */
92 		/* first we add */
93 		s1 = (s1 + *buf);
94 
95 		/* Now if we need to, we do a mod by
96 		 * subtracting. It seems a bit faster
97 		 * since I really will only ever do
98 		 * one subtract at the MOST, since buf[n]
99 		 * is a max of 255.
100 		 */
101 		if (s1 >= BASE)
102 			s1 -= BASE;
103 
104 		/* s2 = (s2 + s1) % BASE */
105 		/* first we add */
106 		s2 = (s2 + s1);
107 
108 		/* again, it is more efficient (it seems) to
109 		 * subtract since the most s2 will ever be
110 		 * is (BASE-1 + BASE-1) in the worse case.
111 		 * This would then be (2 * BASE) - 2, which
112 		 * will still only do one subtract. On Intel
113 		 * this is much better to do this way and
114 		 * avoid the divide. Have not -pg'd on
115 		 * sparc.
116 		 */
117 		if (s2 >= BASE) {
118 			/*      s2 %= BASE;*/
119 			s2 -= BASE;
120 		}
121 	}
122 
123 	/* Return the adler32 of the bytes buf[0..len-1] */
124 	return (s2 << 16) + s1;
125 }
126 
sctp_start_cksum(__u8 * ptr,__u16 count)127 __u32 sctp_start_cksum(__u8 *ptr, __u16 count)
128 {
129 	/*
130 	 * Update a running Adler-32 checksum with the bytes
131 	 * buf[0..len-1] and return the updated checksum. The Adler-32
132 	 * checksum should be initialized to 1.
133 	 */
134 	__u32 adler = 1L;
135 	__u32 zero = 0L;
136 
137 	/* Calculate the CRC up to the checksum field. */
138 	adler = update_adler32(adler, ptr,
139 			       sizeof(struct sctphdr) - sizeof(__u32));
140 	/* Skip over the checksum field. */
141 	adler = update_adler32(adler, (unsigned char *) &zero,
142 			       sizeof(__u32));
143 	ptr += sizeof(struct sctphdr);
144 	count -= sizeof(struct sctphdr);
145 
146 	/* Calculate the rest of the Adler-32. */
147 	adler = update_adler32(adler, ptr, count);
148 
149         return adler;
150 }
151 
sctp_update_cksum(__u8 * ptr,__u16 count,__u32 adler)152 __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 adler)
153 {
154 	adler = update_adler32(adler, ptr, count);
155 
156 	return adler;
157 }
158 
sctp_update_copy_cksum(__u8 * to,__u8 * from,__u16 count,__u32 adler)159 __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 count, __u32 adler)
160 {
161 	/* Its not worth it to try harder.  Adler32 is obsolescent. */
162 	adler = update_adler32(adler, from, count);
163 	memcpy(to, from, count);
164 
165 	return adler;
166 }
167 
sctp_end_cksum(__u32 adler)168 __u32 sctp_end_cksum(__u32 adler)
169 {
170 	return adler;
171 }
172