draft-ietf-tsvwg-sctpcsum-03.txt   draft-ietf-tsvwg-sctpcsum-04.txt 
Network Working Group R. Stewart Network Working Group R. Stewart
Category: Internet Draft Cisco Systems Category: Internet Draft Cisco Systems
J. Stone J. Stone
Stanford Stanford
D. Otis D. Otis
SANlight SANlight
March 1, 2002 March 22, 2002
SCTP Checksum Change SCTP Checksum Change
draft-ietf-tsvwg-sctpcsum-03.txt draft-ietf-tsvwg-sctpcsum-04.txt
Status of this Memo Status of this Memo
This document is an internet-draft and is in full conformance with all This document is an internet-draft and is in full conformance with all
provisions of Section 10 of RFC2026. provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering Task Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other groups Force (IETF), its areas, and its working groups. Note that other groups
may also distribute working documents as Internet-Drafts. Internet- may also distribute working documents as Internet-Drafts. Internet-
Drafts are draft documents valid for a maximum of six months and may be Drafts are draft documents valid for a maximum of six months and may be
skipping to change at page 1, line 42 skipping to change at page 1, line 42
Abstract Abstract
SCTP [RFC2960] currently uses an Adler-32 checksum. For small packets SCTP [RFC2960] currently uses an Adler-32 checksum. For small packets
Adler-32 provides weak detection of errors. This document changes that Adler-32 provides weak detection of errors. This document changes that
checksum and updates SCTP to use a 32 bit CRC checksum. checksum and updates SCTP to use a 32 bit CRC checksum.
Table of Contents Table of Contents
1 Introduction ................................................ 1 1 Introduction ................................................ 1
2 Checksum Procedures ......................................... 2 2 Checksum Procedures ......................................... 2
3 Security Considerations...................................... 5 3 Security Considerations......................................6
4 IANA Considerations.......................................... 5 4 IANA Considerations..........................................6
5 Acknowledgments ............................................. 5 5 Acknowledgments .............................................6
6 Authors' Addresses .......................................... 6 6 Authors' Addresses .......................................... 6
7 References .................................................. 7 7 References .................................................. 7
8 Appendix .................................................... 8 8 Appendix .................................................... 8
1 Introduction 1 Introduction
A fundamental weakness has been detected in SCTP's current Adler-32 A fundamental weakness has been detected in SCTP's current Adler-32
checksum algorithm [STONE]. One requirement of an effective checksum is checksum algorithm [STONE]. One requirement of an effective checksum is
that it evenly and smoothly spreads its input packets over the available that it evenly and smoothly spreads its input packets over the available
check bits. check bits.
skipping to change at page 4, line 26 skipping to change at page 4, line 26
using a consistent mapping. using a consistent mapping.
The SCTP transport-level CRC value should be calculated as follows: The SCTP transport-level CRC value should be calculated as follows:
- CRC input data are assumed to a byte stream numbered from 0 - CRC input data are assumed to a byte stream numbered from 0
to N-1. to N-1.
- the transport-level byte-stream is mapped to a polynomial value. - the transport-level byte-stream is mapped to a polynomial value.
An N-byte PDU with bytes 0 to N-1, is considered as An N-byte PDU with bytes 0 to N-1, is considered as
coefficients of a polynomial M(x) of order 8N-1, with coefficients of a polynomial M(x) of order 8N-1, with
bit 0 of byte j being coefficient x^(8j-1), bit 7 of byte bit 0 of byte j being coefficient x^(8j-1), bit 7 of byte
0 being coefficient x(8j^-8). 0 being coefficient x(8j^-8).
- the CRC remainder register is initialized with all - the CRC remainder register is initialized with all 1s
1s (equivalent to complementing the first 32 bits of the message) 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 polynomial is multiplied by x^32 and divided by G(x),
the generator polynomial, producing a remainder R(x) of degree the generator polynomial, producing a remainder R(x) of degree
less than or equal to 31. less than or equal to 31.
- the coefficients of R(x) are considered a 32 bit sequence. - the coefficients of R(x) are considered a 32 bit sequence.
- the bit sequence is complemented. The resulting is the CRC - the bit sequence is complemented. The resulting is the CRC
polynomial. polynomial.
- The CRC polynomial is mapped back into SCTP transport-level - The CRC polynomial is mapped back into SCTP transport-level
bytes. Coefficient of x^31 gives the value of bit 0 of bytes. Coefficient of x^31 gives the value of bit 0 of
SCTP byte 0, the coefficient of x^24 gives the value 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 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. bit 0 and the coefficient of x^0 0 gives bit 7 of byte 3.
The resulting four-byte transport-level sequence is the The resulting four-byte transport-level sequence is the
32-bit SCTP checksum value. 32-bit 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 long-division
algorithm is initialized to zero rather than all-1s, and instead the
first 32 bits of the message are complemented. The long-division
algorithm used in our formulation is specified such that the the
initial multiplication by 2^32 and the long-division, 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 long-division algorithm.
The choice of formulation in this document is to permit non-SCTP
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 When an SCTP packet is transmitted, the sender MUST perform this
checksum procedure, using the preceding CRC computation: checksum procedure, using the preceding CRC computation:
1) Fill in the proper Verification Tag in the SCTP common header and 1) Fill in the proper Verification Tag in the SCTP common header and
initialize the Checksum field to 0's. initialize the Checksum field to 0's.
2) Calculate the CRC-32c of the whole packet, including the SCTP common 2) Calculate the CRC-32c of the whole packet, including the SCTP common
header and all the chunks. header and all the chunks.
3) Put the resultant 32-bit SCTP checksum value into the Checksum field 3) Put the resultant 32-bit SCTP checksum value into the Checksum field
skipping to change at page 12, line 51 skipping to change at page 13, line 19
unsigned char byte0,byte1,byte2,byte3; unsigned char byte0,byte1,byte2,byte3;
for (i = 0; i < length; i++){ for (i = 0; i < length; i++){
CRC32C(crc32, buffer[i]); CRC32C(crc32, buffer[i]);
} }
result = ~crc32; result = ~crc32;
/* result now holds the negated polynomial remainder; /* result now holds the negated polynomial remainder;
* since the table and algorithm is "reflected" [williams95]. * since the table and algorithm is "reflected" [williams95].
* That is, result has the same value as if we mapped the message * That is, result has the same value as if we mapped the message
* to a polyomial, computed the host-bit-order polynomial * to a polynomial, computed the host-bit-order polynomial
* remainder, performed final negation, then did an end-for-end * remainder, performed final negation, then did an end-for-end
* bit-reversal. * bit-reversal.
* Note that a 32-bit bit-reversal is identical to four inplace * Note that a 32-bit bit-reversal is identical to four inplace
* 8-bit reversals followed by an end-for-end byteswap. * 8-bit reversals followed by an end-for-end byteswap.
* In other words, the bytes of each bit are in the right order, * 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 * but the bytes have been byteswapped. So we now do an explicit
* byteswap. On a little-endian machine, this byteswap and * byteswap. On a little-endian machine, this byteswap and
* the final ntohl cancel out and could be elided. * the final ntohl cancel out and could be elided.
*/ */
byte0 = result & 0xff; byte0 = result & 0xff;
byte1 = (result>>8) & 0xff; byte1 = (result>>8) & 0xff;
byte2 = (result>>16) & 0xff; byte2 = (result>>16) & 0xff;
byte3 = (result>>24) & 0xff; byte3 = (result>>24) & 0xff;
skipping to change at page 13, line 34 skipping to change at page 13, line 53
{ {
SCTP_message *message; SCTP_message *message;
unsigned long crc32; unsigned long crc32;
message = (SCTP_message *) buffer; message = (SCTP_message *) buffer;
message->common_header.checksum = 0L; message->common_header.checksum = 0L;
crc32 = generate_crc32c(buffer,length); crc32 = generate_crc32c(buffer,length);
/* and insert it into the message */ /* and insert it into the message */
message->common_header.checksum = htonl(crc32); message->common_header.checksum = htonl(crc32);
return 1; 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 int
validate_crc32(unsigned char *buffer, unsigned int length) validate_crc32(unsigned char *buffer, unsigned int length)
{ {
SCTP_message *message; SCTP_message *message;
unsigned int i; unsigned int i;
unsigned long original_crc32; unsigned long original_crc32;
unsigned long crc32 = ~0L; unsigned long crc32 = ~0L;
/* save and zero checksum */ /* save and zero checksum */
 End of changes. 

This html diff was produced by rfcdiff 1.23, available from http://www.levkowetz.com/ietf/tools/rfcdiff/