 1/draftietftsvwgsctpcsum03.txt 20060205 02:05:03.000000000 +0100
+++ 2/draftietftsvwgsctpcsum04.txt 20060205 02:05:03.000000000 +0100
@@ 1,22 +1,22 @@
Network Working Group R. Stewart
Category: Internet Draft Cisco Systems
J. Stone
Stanford
D. Otis
SANlight
 March 1, 2002
+ March 22, 2002
SCTP Checksum Change
 draftietftsvwgsctpcsum03.txt
+ draftietftsvwgsctpcsum04.txt
Status of this Memo
This document is an internetdraft and is in full conformance with all
provisions of Section 10 of RFC2026.
InternetDrafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other groups
may also distribute working documents as InternetDrafts. Internet
Drafts are draft documents valid for a maximum of six months and may be
@@ 31,23 +31,23 @@
Abstract
SCTP [RFC2960] currently uses an Adler32 checksum. For small packets
Adler32 provides weak detection of errors. This document changes that
checksum and updates SCTP to use a 32 bit CRC checksum.
Table of Contents
1 Introduction ................................................ 1
2 Checksum Procedures ......................................... 2
 3 Security Considerations...................................... 5
 4 IANA Considerations.......................................... 5
 5 Acknowledgments ............................................. 5
+ 3 Security Considerations......................................6
+ 4 IANA Considerations..........................................6
+ 5 Acknowledgments .............................................6
6 Authors' Addresses .......................................... 6
7 References .................................................. 7
8 Appendix .................................................... 8
1 Introduction
A fundamental weakness has been detected in SCTP's current Adler32
checksum algorithm [STONE]. One requirement of an effective checksum is
that it evenly and smoothly spreads its input packets over the available
check bits.
@@ 176,36 +176,54 @@
using a consistent mapping.
The SCTP transportlevel CRC value should be calculated as follows:
 CRC input data are assumed to a byte stream numbered from 0
to N1.
 the transportlevel bytestream is mapped to a polynomial value.
An Nbyte PDU with bytes 0 to N1, is considered as
coefficients of a polynomial M(x) of order 8N1, with
bit 0 of byte j being coefficient x^(8j1), bit 7 of byte
0 being coefficient x(8j^8).
  the CRC remainder register is initialized with all
 1s (equivalent to complementing the first 32 bits of the message)
+  the CRC remainder register is initialized with all 1s
+ and the CRC is computed with an algorithm that
+ simultaneously multiplies by x^32 and divides by the CRC
+ polynomial.
 the polynomial is multiplied by x^32 and divided by G(x),
the generator polynomial, producing a remainder R(x) of degree
less than or equal to 31.
 the coefficients of R(x) are considered a 32 bit sequence.
 the bit sequence is complemented. The resulting is the CRC
polynomial.
 The CRC polynomial is mapped back into SCTP transportlevel
bytes. Coefficient of x^31 gives the value of bit 0 of
SCTP byte 0, the coefficient of x^24 gives the value of
bit 7 of byte 0. the coefficient of x^7 gives bit 0 of
bit 0 and the coefficient of x^0 0 gives bit 7 of byte 3.
The resulting fourbyte transportlevel sequence is the
32bit SCTP checksum value.
+ IMPLEMENTATION NOTE: Standards documents, textbooks, and vendor
+ literature on CRCs often follow an alternative formulation, in which
+ the register used to hold the remainder of the longdivision
+ algorithm is initialized to zero rather than all1s, and instead the
+ first 32 bits of the message are complemented. The longdivision
+ algorithm used in our formulation is specified such that the the
+ initial multiplication by 2^32 and the longdivision, into one
+ simultaneous operation. For such algorithms, and for messages longer
+ than 64 bits, the two specifications are precisely equivalent. That
+ equivalence is the intent of this document. Implementors of SCTP are
+ warned that both specifications are to be found in the literature,
+ sometimes with no restriction on the longdivision algorithm.
+ The choice of formulation in this document is to permit nonSCTP
+ usage, where the same CRC algorithm may be used to protect messages
+ shorter than 64 bits.
+
When an SCTP packet is transmitted, the sender MUST perform this
checksum procedure, using the preceding CRC computation:
1) Fill in the proper Verification Tag in the SCTP common header and
initialize the Checksum field to 0's.
2) Calculate the CRC32c of the whole packet, including the SCTP common
header and all the chunks.
3) Put the resultant 32bit SCTP checksum value into the Checksum field
@@ 628,26 +646,25 @@
unsigned char byte0,byte1,byte2,byte3;
for (i = 0; i < length; i++){
CRC32C(crc32, buffer[i]);
}
result = ~crc32;
/* result now holds the negated polynomial remainder;
* since the table and algorithm is "reflected" [williams95].
* That is, result has the same value as if we mapped the message
 * to a polyomial, computed the hostbitorder polynomial
+ * to a polynomial, computed the hostbitorder polynomial
* remainder, performed final negation, then did an endforend
* bitreversal.
* Note that a 32bit bitreversal is identical to four inplace
* 8bit reversals followed by an endforend byteswap.

* In other words, the bytes of each bit are in the right order,
* but the bytes have been byteswapped. So we now do an explicit
* byteswap. On a littleendian machine, this byteswap and
* the final ntohl cancel out and could be elided.
*/
byte0 = result & 0xff;
byte1 = (result>>8) & 0xff;
byte2 = (result>>16) & 0xff;
byte3 = (result>>24) & 0xff;
@@ 664,25 +681,20 @@
SCTP_message *message;
unsigned long crc32;
message = (SCTP_message *) buffer;
message>common_header.checksum = 0L;
crc32 = generate_crc32c(buffer,length);
/* and insert it into the message */
message>common_header.checksum = htonl(crc32);
return 1;
}
 /* Example of crc validation */
 /* Test of 32 zeros should yield 0x756EC955 placed in network order */
 /* 13 zeros followed by byte values of 1  0x1f should yield
 /* 0x5b988D47 */

int
validate_crc32(unsigned char *buffer, unsigned int length)
{
SCTP_message *message;
unsigned int i;
unsigned long original_crc32;
unsigned long crc32 = ~0L;
/* save and zero checksum */
message = (SCTP_message *) buffer;