summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc2040.txt
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
commit4bfd864f10b68b71482b35c818559068ef8d5797 (patch)
treee3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc2040.txt
parentea76e11061bda059ae9f9ad130a9895cc85607db (diff)
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc2040.txt')
-rw-r--r--doc/rfc/rfc2040.txt1627
1 files changed, 1627 insertions, 0 deletions
diff --git a/doc/rfc/rfc2040.txt b/doc/rfc/rfc2040.txt
new file mode 100644
index 0000000..d0ad7f6
--- /dev/null
+++ b/doc/rfc/rfc2040.txt
@@ -0,0 +1,1627 @@
+
+
+
+
+
+
+Network Working Group R. Baldwin
+Request for Comments: 2040 RSA Data Security, Inc.
+Category: Informational R. Rivest
+ MIT Laboratory for Computer Science
+ and RSA Data Security, Inc.
+ October 1996
+
+
+ The RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS Algorithms
+
+Status of this Memo
+
+ This memo provides information for the Internet community. This memo
+ does not specify an Internet standard of any kind. Distribution of
+ this memo is unlimited.
+
+Acknowledgments
+
+ We would like to thank Steve Dusse, Victor Chang, Tim Mathews, Brett
+ Howard, and Burt Kaliski for helpful suggestions.
+
+Table of Contents
+
+ 1. Executive Summary ....................... 1
+ 2. Overview ................................ 2
+ 3. Terminology and Notation ................ 3
+ 4. Description of RC5 Keys ................. 4
+ 5. Description of RC5 Key Expansion ........ 6
+ 6. Description of RC5 Block Cipher ......... 10
+ 7. Description of RC5-CBC and RC5-CBC-Pad .. 12
+ 8. Description of RC5-CTS .................. 18
+ 9. Test Program and Vectors ................ 19
+ 10. Security Considerations ................. 26
+ 11. ASN.1 Identifiers ....................... 28
+ References ........................................ 28
+ Authors' Addresses ................................ 29
+
+1. Executive Summary
+
+ This document defines four ciphers with enough detail to ensure
+ interoperability between different implementations. The first cipher
+ is the raw RC5 block cipher. The RC5 cipher takes a fixed size input
+ block and produces a fixed sized output block using a transformation
+ that depends on a key. The second cipher, RC5-CBC, is the Cipher
+ Block Chaining (CBC) mode for RC5. It can process messages whose
+ length is a multiple of the RC5 block size. The third cipher, RC5-
+ CBC-Pad, handles plaintext of any length, though the ciphertext will
+ be longer than the plaintext by at most the size of a single RC5
+
+
+
+Baldwin & Rivest Informational [Page 1]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ block. The RC5-CTS cipher is the Cipher Text Stealing mode of RC5,
+ which handles plaintext of any length and the ciphertext length
+ matches the plaintext length.
+
+ The RC5 cipher was invented by Professor Ronald L. Rivest of the
+ Massachusetts Institute of Technology in 1994. It is a very fast and
+ simple algorithm that is parameterized by the block size, the number
+ of rounds, and key length. These parameters can be adjusted to meet
+ different goals for security, performance, and exportability.
+
+ RSA Data Security Incorporated has filed a patent application on the
+ RC5 cipher and for trademark protection for RC5, RC5-CBC, RC5-CBC-
+ Pad, RC5-CTS and assorted variations.
+
+2. Overview
+
+ This memo is a restatement of existing published material. The
+ description of RC5 follows the notation and order of explanation
+ found in the original RC5 paper by Professor Rivest [2]. The CBC
+ mode appears in reference works such as the one by Bruce Schneier
+ [6]. The CBC-Pad mode is the same as in the Public Key Cryptography
+ Standard (PKCS) number five [5]. Sample C code [8] is included for
+ clarity only and is equivalent to the English language descriptions.
+
+ The ciphers will be explained in a bottom up object-oriented fashion.
+ First, RC5 keys will be presented along with the key expansion
+ algorithm. Second, the RC5 block cipher is explained, and finally,
+ the RC5-CBC and RC5-CBC-Pad ciphers are specified. For brevity, only
+ the encryption process is described. Decryption is achieved by
+ inverting the steps of encryption.
+
+ The object-oriented description found here should make it easier to
+ implement interoperable systems, though it is not as terse as the
+ functional descriptions found in the references. There are two
+ classes of objects, keys and cipher algorithms. Both classes share
+ operations that create and destroy these objects in a manner that
+ ensures that secret information is not returned to the memory
+ manager.
+
+ Keys also have a "set" operation that copies a secret key into the
+ object. The "set" operation for the cipher objects defines the
+ number of rounds, and the initialization vector.
+
+ There are four operations for the cipher objects described in this
+ memo. There is binding a key to a cipher object, setting a new
+ initialization vector for a cipher object without changing the key,
+ encrypting part of a message (this would be performed multiple times
+ for long messages), and processing the last part of a message which
+
+
+
+Baldwin & Rivest Informational [Page 2]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ may add padding or check the length of the message.
+
+ In summary, the cipher will be explained in terms of these
+ operations:
+
+ RC5_Key_Create - Create a key object.
+
+ RC5_Key_Destroy - Destroy a key object.
+
+ RC5_Key_Set - Bind a user key to a key object.
+
+ RC5_CBC_Create - Create a cipher object.
+
+ RC5_CBC_Destroy - Destroy a cipher object.
+
+ RC5_CBC_Encrypt_Init - Bind a key object to a cipher object.
+
+ RC5_CBC_SetIV - Set a new IV without changing the key.
+
+ RC5_CBC_Encrypt_Update - Process part of a message.
+
+ RC5_CBC_Encrypt_Final - Process the end of a message.
+
+3. Terminology and Notation
+
+ The term "word" refers to a string of bits of a particular length
+ that can be operated on as either an unsigned integer or as a bit
+ vector. For example a "word" might be 32 or 64 bits long depending
+ on the desired block size for the RC5 cipher. A 32 bit word will
+ produce a 64 bit block size. For best performance the RC5 word size
+ should match the register size of the CPU. The term "byte" refers to
+ eight bits.
+
+ The following variables will be used throughout this memo with these
+ meanings:
+
+ W This is the word size for RC5 measured in bits. It is half the
+ block size. The word sizes covered by this memo are 32 and 64.
+
+ WW This is the word size for RC5 measured in bytes.
+
+ B This is the block size for RC5 measured in bits. It is twice
+ the word size. When RC5 is used as a 64 bit block cipher, B is
+ 64 and W is 32. 0 < B < 257. In the sample code, B, is used as
+ a variable instead of a cipher system parameter, but this usage
+ should be obvious from context.
+
+ BB This is the block size for RC5 measured in bytes. BB = B / 8.
+
+
+
+Baldwin & Rivest Informational [Page 3]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ b This is the byte length of the secret key. 0 <= b < 256.
+
+ K This is the secret key which is treated as a sequence of b
+ bytes indexed by: K[0], ..., K[b-1].
+
+ R This is the number of rounds of the inner RC5 transform.
+ 0 <= R < 256.
+
+ T This is the number of words in the expanded key table. It is
+ always 2*(R + 1). 1 < T < 513.
+
+ S This is the expanded key table which is treated as a sequence
+ of words indexed by: S[0], ..., S[T-1].
+
+ N This is the byte length of the plaintext message.
+
+ P This is the plaintext message which is treated as a sequence of
+ N bytes indexed by: P[0], ..., P[N-1].
+
+ C This is the ciphertext output which is treated as a sequence of
+ bytes indexed by: C[0], C[1], ...
+
+ I This is the initialization vector for the CBC mode which is
+ treated as a sequence of bytes indexed by: I[0], ..., I[BB-1].
+
+4. Description of RC5 Keys
+
+ Like most block ciphers, RC5 expands a small user key into a table of
+ internal keys. The byte length of the user key is one of the
+ parameters of the cipher, so the RC5 user key object must be able to
+ hold variable length keys. A possible structure for this in C is:
+
+ /* Definition of RC5 user key object. */
+ typedef struct rc5UserKey
+ {
+ int keyLength; /* In Bytes. */
+ unsigned char *keyBytes;
+ } rc5UserKey;
+
+ The basic operations on a key are to create, destroy and set. To
+ avoid exposing key material to other parts of an application, the
+ destroy operation zeros the memory allocated for the key before
+ releasing it to the memory manager. A general key object may support
+ other operations such as generating a new random key and deriving a
+ key from key-agreement information.
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 4]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+4.1 Creating an RC5 Key
+
+ To create a key, the memory for the key object must be allocated and
+ initialized. The C code below assumes that a function called
+ "malloc" will return a block of uninitialized memory from the heap,
+ or zero indicating an error.
+
+ /* Allocate and initialize an RC5 user key.
+ * Return 0 if problems.
+ */
+ rc5UserKey *RC5_Key_Create ()
+ {
+ rc5UserKey *pKey;
+
+ pKey = (rc5UserKey *) malloc (sizeof(*pKey));
+ if (pKey != ((rc5UserKey *) 0))
+ {
+ pKey->keyLength = 0;
+ pKey->keyBytes = (unsigned char *) 0;
+ }
+ return (pKey);
+ }
+
+4.2 Destroying an RC5 Key
+
+ To destroy a key, the memory must be zeroed and released to the
+ memory manager. The C code below assumes that a function called
+ "free" will return a block of memory to the heap.
+
+ /* Zero and free an RC5 user key.
+ */
+ void RC5_Key_Destroy (pKey)
+ rc5UserKey *pKey;
+ {
+ unsigned char *to;
+ int count;
+
+ if (pKey == ((rc5UserKey *) 0))
+ return;
+ if (pKey->keyBytes == ((unsigned char *) 0))
+ return;
+ to = pKey->keyBytes;
+ for (count = 0 ; count < pKey->keyLength ; count++)
+ *to++ = (unsigned char) 0;
+ free (pKey->keyBytes);
+ pKey->keyBytes = (unsigned char *) 0;
+ pKey->keyLength = 0;
+ free (pKey);
+
+
+
+Baldwin & Rivest Informational [Page 5]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ }
+
+4.3 Setting an RC5 Key
+
+ Setting the key object makes a copy of the secret key into a block of
+ memory allocated from the heap.
+
+ /* Set the value of an RC5 user key.
+ * Copy the key bytes so the caller can zero and
+ * free the original.
+ * Return zero if problems
+ */
+ int RC5_Key_Set (pKey, keyLength, keyBytes)
+ rc5UserKey *pKey;
+ int keyLength;
+ unsigned char *keyBytes;
+ {
+ unsigned char *keyBytesCopy;
+ unsigned char *from, *to;
+ int count;
+
+ keyBytesCopy = (unsigned char *) malloc (keyLength);
+ if (keyBytesCopy == ((unsigned char *) 0))
+ return (0);
+ from = keyBytes;
+ to = keyBytesCopy;
+ for (count = 0 ; count < keyLength ; count++)
+ *to++ = *from++;
+ pKey->keyLength = count;
+ pKey->keyBytes = keyBytesCopy;
+ return (1);
+ }
+
+5. Description of RC5 Key Expansion
+
+ This section describes the key expansion algorithm. To be specific,
+ the sample code assumes that the block size is 64 bits. Several
+ programming parameters depend on the block size.
+
+ /* Definitions for RC5 as a 64 bit block cipher. */
+ /* The "unsigned int" will be 32 bits on all but */
+ /* the oldest compilers, which will make it 16 bits. */
+ /* On a DEC Alpha "unsigned long" is 64 bits, not 32. */
+ #define RC5_WORD unsigned int
+ #define W (32)
+ #define WW (W / 8)
+ #define ROT_MASK (W - 1)
+ #define BB ((2 * W) / 8) /* Bytes per block */
+
+
+
+Baldwin & Rivest Informational [Page 6]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ /* Define macros used in multiple procedures. */
+ /* These macros assumes ">>" is an unsigned operation, */
+ /* and that x and s are of type RC5_WORD. */
+ #define SHL(x,s) ((RC5_WORD)((x)<<((s)&ROT_MASK)))
+ #define SHR(x,s,w) ((RC5_WORD)((x)>>((w)-((s)&ROT_MASK))))
+ #define ROTL(x,s,w) ((RC5_WORD)(SHL((x),(s))|SHR((x),(s),(w))))
+
+5.1 Definition of initialization constants
+
+ Two constants, Pw and Qw, are defined for any word size W by the
+ expressions:
+
+ Pw = Odd((e-2)*2**W)
+
+ Qw = Odd((phi-1)*2**W)
+
+ where e is the base of the natural logarithm (2.71828 ...), and phi
+ is the golden ratio (1.61803 ...), and 2**W is 2 raised to the power
+ of W, and Odd(x) is equal to x if x is odd, or equal to x plus one if
+ x is even. For W equal to 16, 32, and 64, the Pw and Qw constants
+ are the following hexadecimal values:
+
+ #define P16 0xb7e1
+ #define Q16 0x9e37
+ #define P32 0xb7e15163
+ #define Q32 0x9e3779b9
+ #define P64 0xb7e151628aed2a6b
+ #define Q64 0x9e3779b97f4a7c15
+ #if W == 16
+ #define Pw P16 /* Select 16 bit word size */
+ #define Qw Q16
+ #endif
+ #if W == 32
+ #define Pw P32 /* Select 32 bit word size */
+ #define Qw Q32
+ #endif
+ #if W == 64
+ #define Pw P64 /* Select 64 bit word size */
+ #define Qw Q64
+ #endif
+
+
+
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 7]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+5.2 Interface definition
+
+ The key expansion routine converts the b-byte secret key, K, into an
+ expanded key, S, which is a sequence of T = 2*(R+1) words. The
+ expansion algorithm uses two constants that are derived from the
+ constants, e, and phi. These are used to initialize S, which is then
+ modified using K. A C code procedure header for this routine could
+ be:
+
+ /* Expand an RC5 user key.
+ */
+ void RC5_Key_Expand (b, K, R, S)
+ int b; /* Byte length of secret key */
+ char *K; /* Secret key */
+ int R; /* Number of rounds */
+ RC5_WORD *S; /* Expanded key buffer, 2*(R+1) words */
+ {
+
+5.3 Convert secret key from bytes to words
+
+ This step converts the b-byte key into a sequence of words stored in
+ the array L. On a little-endian processor this is accomplished by
+ zeroing the L array and copying in the b bytes of K. The following C
+ code will achieve this effect on all processors:
+
+ int i, j, k, LL, t, T;
+ RC5_WORD L[256/WW]; /* Based on max key size */
+ RC5_WORD A, B;
+
+ /* LL is number of elements used in L. */
+ LL = (b + WW - 1) / WW;
+ for (i = 0 ; i < LL ; i++) {
+ L[i] = 0;
+ }
+ for (i = 0 ; i < b ; i++) {
+ t = (K[i] & 0xFF) << (8*(i%4)); /* 0, 8, 16, 24*/
+ L[i/WW] = L[i/WW] + t;
+ }
+
+5.4 Initialize the expanded key table
+
+ This step fills in the S table with a fixed (key independent)
+ pseudo-random pattern using an arithmetic progression based on Pw and
+ Qw modulo 2**W. The element S[i] equals i*Qw + Pw modulo 2**W. This
+ table could be precomputed and copied as needed or computed on the
+ fly. In C code it can be computed by:
+
+
+
+
+
+Baldwin & Rivest Informational [Page 8]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ T = 2*(R+1);
+ S[0] = Pw;
+ for (i = 1 ; i < T ; i++) {
+ S[i] = S[i-1] + Qw;
+ }
+
+5.5 Mix in the secret key
+
+ This step mixes the secret key, K, into the expanded key, S. First
+ the number of iterations of the mixing function, k, is set to three
+ times the maximum of the number of initialized elements of L, called
+ LL, and the number of elements in S, called T. Each iteration is
+ similar to an interation of the encryption inner loop in that two
+ variables A and B are updated by the first and second halves of the
+ iteration.
+
+ Initially A and B are zero as are the indexes into the S array, i,
+ and the L array, j. In the first half of the iteration, a partial
+ result is computed by summing S[i], A and B. The new value for A is
+ this partial result rotated left three bits. The A value is then
+ placed into S[i]. The second half of the iteration computes a second
+ partial result that is the sum of L[j], A and B. The second partial
+ result is then rotated left by A+B bit positions and set to be the
+ new value for B. The new B value is then placed into L[j]. At the
+ end of the iteration, i and j are incremented modulo the size of
+ their respective arrays. In C code:
+
+ i = j = 0;
+ A = B = 0;
+ if (LL > T)
+ k = 3 * LL; /* Secret key len > expanded key. */
+ else
+ k = 3 * T; /* Secret key len < expanded key. */
+ for ( ; k > 0 ; k--) {
+ A = ROTL(S[i] + A + B, 3, W);
+ S[i] = A;
+ B = ROTL(L[j] + A + B, A + B, W);
+ L[j] = B;
+ i = (i + 1) % T;
+ j = (j + 1) % LL;
+ }
+ return;
+ } /* End of RC5_Key_Expand */
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 9]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+6. Description of RC5 Block Cipher
+
+ This section describes the RC5 block cipher by explaining the steps
+ required to perform an encryption of a single input block. The
+ decryption process is the reverse of these steps so it will not be
+ explained. The RC5 cipher is parameterized by a version number, V, a
+ round count, R, and a word size in bits, W. This description
+ corresponds to original version of RC5 (V = 16 decimal) and covers
+ any positive value for R and the values 16, 32, and 64 for W.
+
+ The inputs to this process are the expanded key table, S, the number
+ of rounds, R, the input buffer pointer, in, and the output buffer
+ pointer, out. A possible C code procedure header for this would be:
+
+ void RC5_Block_Encrypt (S, R, in, out)
+ RC5_WORD *S;
+ int R;
+ char *in;
+ char *out;
+ {
+
+6.1 Loading A and B values
+
+ This step converts input bytes into two unsigned integers called A
+ and B. When RC5 is used as a 64 bit block cipher A and B are 32 bit
+ values. The first input byte becomes the least significant byte of
+ A, the fourth input byte becomes the most significant byte of A, the
+ fifth input byte becomes the least significant byte of B and the last
+ input byte becomes the most significant byte of B. This conversion
+ can be very efficient for little-endian processors such as the Intel
+ family. In C code this could be expressed as:
+
+ int i;
+ RC5_WORD A, B;
+
+ A = in[0] & 0xFF;
+ A += (in[1] & 0xFF) << 8;
+ A += (in[2] & 0xFF) << 16;
+ A += (in[3] & 0xFF) << 24;
+ B = in[4] & 0xFF;
+ B += (in[5] & 0xFF) << 8;
+ B += (in[6] & 0xFF) << 16;
+ B += (in[7] & 0xFF) << 24;
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 10]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+6.2 Iterating the round function
+
+ This step mixes the expanded key with the input to perform the
+ fundamental encryption operation. The first two words of the
+ expanded key are added to A and B respectively, and then the round
+ function is repeated R times.
+
+ The first half of the round function computes a new value for A based
+ on the values of A, B, and the next unused word in the expanded key
+ table. Specifically, A is XOR'ed with B and then this first partial
+ result is rotated to the left by an amount specified by B to form the
+ second partial result. The rotation is performed on a W bit boundary
+ (i.e., 32 bit rotation for the version of RC5 that has a 64 bit block
+ size). The actual rotation amount only depends on the least
+ significant log base-2 of W bits of B. The next unused word of the
+ expanded key table is then added to the second partial result and
+ this becomes the new value for A.
+
+ The second half of the round function is identical except the roles
+ of A and B are switched. Specifically, B is exclusive or'ed with A
+ and then this first partial result is rotated to the left by an
+ amount specified by A to form the second partial result. The next
+ unused word of the expanded key table is then added to the second
+ partial result and this becomes the new value for B.
+
+ One way to express this in C code is:
+
+ A = A + S[0];
+ B = B + S[1];
+ for (i = 1 ; i <= R ; i++) {
+ A = A ^ B;
+ A = ROTL(A, B, W) + S[2*i];
+ B = B ^ A;
+ B = ROTL(B, A, W) + S[(2*i)+1];
+ }
+
+6.3 Storing the A and B values
+
+ The final step is to convert A and B back into a sequence of bytes.
+ This is the inverse of the load operation. An expression of this in
+ C code could be:
+
+ out[0] = (A >> 0) & 0xFF;
+ out[1] = (A >> 8) & 0xFF;
+ out[2] = (A >> 16) & 0xFF;
+ out[3] = (A >> 24) & 0xFF;
+ out[4] = (B >> 0) & 0xFF;
+ out[5] = (B >> 8) & 0xFF;
+
+
+
+Baldwin & Rivest Informational [Page 11]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ out[6] = (B >> 16) & 0xFF;
+ out[7] = (B >> 24) & 0xFF;
+ return;
+ } /* End of RC5_Block_Encrypt */
+
+7. Description of RC5-CBC and RC5-CBC-Pad
+
+ This section describes the CBC and CBC-Pad modes of the RC5 cipher.
+ This description is based on the RC5 key objects and RC5 block cipher
+ described earlier.
+
+7.1 Creating cipher objects
+
+ The cipher object needs to keep track of the padding mode, the number
+ of rounds, the expanded key, the initialization vector, the CBC
+ chaining block, and an input buffer. A possible structure definition
+ for this in C code would be:
+
+ /* Definition of the RC5 CBC algorithm object.
+ */
+ typedef struct rc5CBCAlg
+ {
+ int Pad; /* 1 = RC5-CBC-Pad, 0 = RC5-CBC. */
+ int R; /* Number of rounds. */
+ RC5_WORD *S; /* Expanded key. */
+ unsigned char I[BB]; /* Initialization vector. */
+ unsigned char chainBlock[BB];
+ unsigned char inputBlock[BB];
+ int inputBlockIndex; /* Next inputBlock byte. */
+ } rc5CBCAlg;
+
+ To create a cipher algorithm object, the parameters must be checked
+ and then space allocated for the expanded key table. The expanded
+ key is initialized using the method described earlier. Finally, the
+ state variables (padding mode, number of rounds, and the input
+ buffer) are set to their initial values. In C this could be
+ accomplished by:
+
+ /* Allocate and initialize the RC5 CBC algorithm object.
+ * Return 0 if problems.
+ */
+ rc5CBCAlg *RC5_CBC_Create (Pad, R, Version, bb, I)
+ int Pad; /* 1 = RC5-CBC-Pad, 0 = RC5-CBC. */
+ int R; /* Number of rounds. */
+ int Version; /* RC5 version number. */
+ int bb; /* Bytes per RC5 block == IV len. */
+ char *I; /* CBC IV, bb bytes long. */
+ {
+
+
+
+Baldwin & Rivest Informational [Page 12]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ rc5CBCAlg *pAlg;
+ int index;
+
+ if ((Version != RC5_FIRST_VERSION) ||
+ (bb != BB) || (R < 0) || (255 < R))
+ return ((rc5CBCAlg *) 0);
+ pAlg = (rc5CBCAlg *) malloc (sizeof(*pAlg));
+ if (pAlg == ((rc5CBCAlg *) 0))
+ return ((rc5CBCAlg *) 0);
+ pAlg->S = (RC5_WORD *) malloc (BB * (R + 1));
+ if (pAlg->S == ((RC5_WORD *) 0)) {
+ free (pAlg);
+ return ((rc5CBCAlg *) 0);
+ }
+ pAlg->Pad = Pad;
+ pAlg->R = R;
+ pAlg->inputBlockIndex = 0;
+ for (index = 0 ; index < BB ; index++)
+ pAlg->I[index] = I[index];
+ return (pAlg);
+ }
+
+7.2 Destroying cipher objects
+
+ Destroying the cipher object is the inverse of creating it with care
+ being take to zero memory before returning it to the memory manager.
+ In C this could be accomplished by:
+
+ /* Zero and free an RC5 algorithm object.
+ */
+ void RC5_CBC_Destroy (pAlg)
+ rc5CBCAlg *pAlg;
+ {
+ RC5_WORD *to;
+ int count;
+
+ if (pAlg == ((rc5CBCAlg *) 0))
+ return;
+ if (pAlg->S == ((RC5_WORD *) 0))
+ return;
+ to = pAlg->S;
+ for (count = 0 ; count < (1 + pAlg->R) ; count++)
+ {
+ *to++ = 0; /* Two expanded key words per round. */
+ *to++ = 0;
+ }
+ free (pAlg->S);
+ for (count = 0 ; count < BB ; count++)
+
+
+
+Baldwin & Rivest Informational [Page 13]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ {
+ pAlg->I[count] = (unsigned char) 0;
+ pAlg->inputBlock[count] = (unsigned char) 0;
+ pAlg->chainBlock[count] = (unsigned char) 0;
+ }
+ pAlg->Pad = 0;
+ pAlg->R = 0;
+ pAlg->inputBlockIndex = 0;
+ free (pAlg);
+ }
+
+7.3 Setting the IV for cipher objects
+
+ For CBC cipher objects, the state of the algorithm depends on the
+ expanded key, the CBC chain block, and any internally buffered input.
+ Often the same key is used with many messages that each have a unique
+ initialization vector. To avoid the overhead of creating a new
+ cipher object, it makes more sense to provide an operation that
+ allows the caller to change the initialization vector for an existing
+ cipher object. In C this could be accomplished by the following
+ code:
+
+ /* Setup a new initialization vector for a CBC operation
+ * and reset the CBC object.
+ * This can be called after Final without needing to
+ * call Init or Create again.
+ * Return zero if problems.
+ */
+ int RC5_CBC_SetIV (pAlg, I)
+ rc5CBCAlg *pAlg;
+ char *I; /* CBC Initialization vector, BB bytes. */
+ {
+ int index;
+
+ pAlg->inputBlockIndex = 0;
+ for (index = 0 ; index < BB ; index++)
+ {
+ pAlg->I[index] = pAlg->chainBlock[index] = I[index];
+ pAlg->inputBlock[index] = (unsigned char) 0;
+ }
+ return (1);
+ }
+
+7.4 Binding a key to a cipher object
+
+ The operation that binds a key to a cipher object performs the key
+ expansion. Key expansion could be an operation on keys, but that
+ would not work correctly for ciphers that modify the expanded key as
+
+
+
+Baldwin & Rivest Informational [Page 14]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ they operate. After expanding the key, this operation must
+ initialize the CBC chain block from the initialization vector and
+ prepare the input buffer to receive the first character. In C this
+ could be done by:
+
+ /* Initialize the encryption object with the given key.
+ * After this routine, the caller frees the key object.
+ * The IV for this CBC object can be changed by calling
+ * the SetIV routine. The only way to change the key is
+ * to destroy the CBC object and create a new one.
+ * Return zero if problems.
+ */
+ int RC5_CBC_Encrypt_Init (pAlg, pKey)
+ rc5CBCAlg *pAlg;
+ rc5UserKey *pKey;
+ {
+ if ((pAlg == ((rc5CBCAlg *) 0)) ||
+ (pKey == ((rc5UserKey *) 0)))
+ return (0);
+ RC5_Key_Expand (Key->keyLength, pKey->keyBytes,
+ pAlg->R, pAlg->S);
+ return (RC5_CBC_SetIV(pAlg, pAlg->I));
+ }
+
+7.5 Processing part of a message
+
+ The encryption process described here uses the Init-Update-Final
+ paradigm. The update operation can be performed on a sequence of
+ message parts in order to incrementally produce the ciphertext.
+ After the last part is processed, the Final operation is called to
+ pick up any plaintext bytes or padding that are buffered inside the
+ cipher object. An appropriate procedure header for this operation
+ would be:
+
+ /* Encrypt a buffer of plaintext.
+ * The plaintext and ciphertext buffers can be the same.
+ * The byte len of the ciphertext is put in *pCipherLen.
+ * Call this multiple times passing successive
+ * parts of a large message.
+ * After the last part has been passed to Update,
+ * call Final.
+ * Return zero if problems like output buffer too small.
+ */
+ int RC5_CBC_Encrypt_Update (pAlg, N, P,
+ pCipherLen, maxCipherLen, C)
+ rc5CBCAlg *pAlg; /* Cipher algorithm object. */
+ int N; /* Byte length of P. */
+ char *P; /* Plaintext buffer. */
+
+
+
+Baldwin & Rivest Informational [Page 15]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ int *pCipherLen;/* Gets byte len of C. */
+ int maxCipherLen; /* Size of C. */
+ char *C; /* Ciphertext buffer. */
+ {
+
+7.5.1 Output buffer size check.
+
+ The first step of plaintext processing is to make sure that the
+ output buffer is big enough hold the ciphertext. The ciphertext will
+ be produced in multiples of the block size and depends on the number
+ of plaintext characters passed to this operation plus any characters
+ that are in the cipher object's internal buffer. In C code this
+ would be:
+
+ int plainIndex, cipherIndex, j;
+
+ /* Check size of the output buffer. */
+ if (maxCipherLen < (((pAlg->inputBlockIndex+N)/BB)*BB))
+ {
+ *pCipherLen = 0;
+ return (0);
+ }
+
+7.5.2 Divide plaintext into blocks
+
+ The next step is to add characters to the internal buffer until a
+ full block has been constructed. When that happens, the buffer
+ pointers are reset and the input buffer is exclusive-or'ed (XORed)
+ with the CBC chaining block. The byte order of the chaining block is
+ the same as the input block. For example, the ninth input byte is
+ XOR'ed with the first ciphertext byte. The result is then passed to
+ the RC5 block cipher which was described earlier. To reduce data
+ movement and byte alignment problems, the output of RC5 can be
+ directly written into the CBC chaining block. Finally, this output
+ is copied to the ciphertext buffer provided by the user. Before
+ returning, the actual size of the ciphertext is passed back to the
+ caller. In C, this step can be performed by:
+
+ plainIndex = cipherIndex = 0;
+ while (plainIndex < N)
+ {
+ if (pAlg->inputBlockIndex < BB)
+ {
+ pAlg->inputBlock[pAlg->inputBlockIndex]
+ = P[plainIndex];
+ pAlg->inputBlockIndex++;
+ plainIndex++;
+ }
+
+
+
+Baldwin & Rivest Informational [Page 16]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ if (pAlg->inputBlockIndex == BB)
+ { /* Have a complete input block, process it. */
+ pAlg->inputBlockIndex = 0;
+ for (j = 0 ; j < BB ; j++)
+ { /* XOR in the chain block. */
+ pAlg->inputBlock[j] = pAlg->inputBlock[j]
+ ^ pAlg->chainBlock[j];
+ }
+ RC5_Block_Encrypt(pAlg->S, pAlg->R
+ pAlg->inputBlock,
+ pAlg->chainBlock);
+ for (j = 0 ; j < BB ; j++)
+ { /* Output the ciphertext. */
+ C[cipherIndex] = pAlg->chainBlock[j];
+ cipherIndex++;
+ }
+ }
+ }
+ *pCipherLen = cipherIndex;
+ return (1);
+ } /* End of RC5_CBC_Encrypt_Update */
+
+7.6 Final block processing
+
+ This step handles the last block of plaintext. For RC5-CBC, this
+ step just performs error checking to ensure that the plaintext length
+ was indeed a multiple of the block length. For RC5-CBC-Pad, padding
+ bytes are added to the plaintext. The pad bytes are all the same and
+ are set to a byte that represents the number of bytes of padding.
+ For example if there are eight bytes of padding, the bytes will all
+ have the hexadecimal value 0x08. There will be between one and BB
+ padding bytes, inclusive. In C code this would be:
+
+ /* Produce the final block of ciphertext including any
+ * padding, and then reset the algorithm object.
+ * Return zero if problems.
+ */
+ int RC5_CBC_Encrypt_Final (pAlg, pCipherLen, maxCipherLen, C)
+ rc5CBCAlg *pAlg;
+ int *pCipherLen; /* Gets byte len of C. */
+ int maxCipherLen; /* Len of C buffer. */
+ char *C; /* Ciphertext buffer. */
+ {
+ int cipherIndex, j;
+ int padLength;
+
+ /* For non-pad mode error if input bytes buffered. */
+ *pCipherLen = 0;
+
+
+
+Baldwin & Rivest Informational [Page 17]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ if ((pAlg->Pad == 0) && (pAlg->inputBlockIndex != 0))
+ return (0);
+
+ if (pAlg->Pad == 0)
+ return (1);
+ if (maxCipherLen < BB)
+ return (0);
+
+ padLength = BB - pAlg->inputBlockIndex;
+ for (j = 0 ; j < padLength ; j++)
+ {
+ pAlg->inputBlock[pAlg->inputBlockIndex]
+ = (unsigned char) padLength;
+ pAlg->inputBlockIndex++;
+ }
+ for (j = 0 ; j < BB ; j++)
+ { /* XOR the chain block into the plaintext block. */
+ pAlg->inputBlock[j] = pAlg->inputBlock[j]
+ ^ pAlg->chainBlock[j];
+ }
+ RC5_Block_Encrypt(pAlg->S, pAlg->R,
+ pAlg->inputBlock, pAlg->chainBlock);
+ cipherIndex = 0;
+ for (j = 0 ; j < BB ; j++)
+ { /* Output the ciphertext. */
+ C[cipherIndex] = pAlg->chainBlock[j];
+ cipherIndex++;
+ }
+ *pCipherLen = cipherIndex;
+
+ /* Reset the CBC algorithm object. */
+ return (RC5_CBC_SetIV(pAlg, pAlg->I));
+ } /* End of RC5_CBC_Encrypt_Final */
+
+8. Description of RC5-CTS
+
+ The Cipher Text Stealing (CTS) mode for block ciphers is described by
+ Schneier on pages 195 and 196 of [6]. This mode handles any length
+ of plaintext and produces ciphertext whose length matches the
+ plaintext length. The CTS mode behaves like the CBC mode for all but
+ the last two blocks of the plaintext. The following steps describe
+ how to handle the last two portions of the plaintext, called Pn-1 and
+ Pn, where the length of Pn-1 equals the block size, BB, and the
+ length of the last block, Pn, is Ln bytes. Notice that Ln ranges
+ from 1 to BB, inclusive, so Pn could in fact be a complete block.
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 18]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ 1. Exclusive-or Pn-1 with the previous ciphertext
+ block, Cn-2, to create Xn-1.
+
+ 2. Encrypt Xn-1 to create En-1.
+
+ 3. Select the first Ln bytes of En-1 to create Cn.
+
+ 4. Pad Pn with zeros at the end to create P of length BB.
+
+ 5. Exclusive-or En-1 with P to create to create Dn.
+
+ 6. Encrypt Dn to create Cn-1
+
+ 7. The last two parts of the ciphertext are Cn-1 and
+ Cn respectively.
+
+ To implement CTS encryption, the RC5-CTS object must hold on to
+ (buffer) at most 2*BB bytes of plaintext and process them specially
+ when the RC5_CTS_Encrypt_Final routine is called.
+
+ The following steps describe how to decrypt Cn-1 and Cn.
+
+ 1. Decrypt Cn-1 to create Dn.
+
+ 2. Pad Cn with zeros at the end to create C of length BB.
+
+ 3. Exclusive-or Dn with C to create Xn.
+
+ 4. Select the first Ln bytes of Xn to create Pn.
+
+ 5. Append the tail (BB minus Ln) bytes of Xn to Cn
+ to create En.
+
+ 6. Decrypt En to create Pn-1.
+
+ 7. The last two parts of the plaintext are Pn-1 and
+ Pn respectively.
+
+9. Test Program and Vectors
+
+ To help confirm the correctness of an implementation, this section
+ gives a test program and results from a set of test vectors.
+
+9.1 Test Program
+
+ The following test program written in C reads test vectors from its
+ input stream and writes results on its output stream. The following
+ subsections give a set of test vectors for inputs and the resulting
+
+
+
+Baldwin & Rivest Informational [Page 19]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ outputs.
+
+ #include <stdio.h>
+
+ #define BLOCK_LENGTH (8 /* bytes */)
+ #define MAX_KEY_LENGTH (64 /* bytes */)
+ #define MAX_PLAIN_LENGTH (128 /* bytes */)
+ #define MAX_CIPHER_LENGTH(MAX_PLAIN_LENGTH + BLOCK_LENGTH)
+ #define MAX_ROUNDS (20)
+ #define MAX_S_LENGTH (2 * (MAX_ROUNDS + 1))
+
+ typedef struct test_vector
+ {
+ int padding_mode;
+ int rounds;
+ char keytext[2*MAX_KEY_LENGTH+1];
+ int key_length;
+ char key[MAX_KEY_LENGTH];
+ char ivtext[2*BLOCK_LENGTH+1];
+ int iv_length;
+ char iv[BLOCK_LENGTH];
+ char plaintext[2*MAX_PLAIN_LENGTH+1];
+ int plain_length;
+ char plain[MAX_PLAIN_LENGTH];
+ char ciphertext[2*MAX_CIPHER_LENGTH+1];
+ int cipher_length;
+ char cipher[MAX_CIPHER_LENGTH];
+ RC5_WORD S[MAX_S_LENGTH];
+ } test_vector;
+
+ void show_banner()
+ {
+ (void) printf("RC5 CBC Tester.\n");
+ (void) printf("Each input line should contain the following\n");
+ (void) printf("test parameters separated by a single space:\n");
+ (void) printf("- Padding mode flag. Use 1 for RC5_CBC_Pad, else
+ 0.\n");
+ (void) printf("- Number of rounds for RC5.\n");
+ (void) printf("- Key bytes in hexadecimal. Two characters per
+ byte like '01'.\n");
+ (void) printf("- IV bytes in hexadecimal. Must be 16 hex
+ characters.\n");
+ (void) printf("- Plaintext bytes in hexadecimal.\n");
+ (void) printf("An end of file or format error terminates the
+ tester.\n");
+ (void) printf("\n");
+ }
+
+
+
+
+Baldwin & Rivest Informational [Page 20]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ /* Convert a buffer from ascii hex to bytes.
+ * Set pTo_length to the byte length of the result.
+ * Return 1 if everything went OK.
+ */
+ int hex_to_bytes (from, to, pTo_length)
+ char *from, *to;
+ int *pTo_length;
+ {
+ char *pHex; /* Ptr to next hex character. */
+ char *pByte; /* Ptr to next resulting byte. */
+ int byte_length = 0;
+ int value;
+
+ pByte = to;
+ for (pHex = from ; *pHex != 0 ; pHex += 2) {
+ if (1 != sscanf(pHex, "%02x", &value))
+ return (0);
+ *pByte++ = ((char)(value & 0xFF));
+ byte_length++;
+ }
+ *pTo_length = byte_length;
+ return (1);
+ }
+
+ /* Convert a buffer from bytes to ascii hex.
+ * Return 1 if everything went OK.
+ */
+ int bytes_to_hex (from, from_length, to)
+ char *from, *to;
+ int from_length;
+ {
+ char *pHex; /* Ptr to next hex character. */
+ char *pByte; /* Ptr to next resulting byte. */
+ int value;
+
+ pHex = to;
+ for (pByte = from ; from_length > 0 ; from_length--) {
+ value = *pByte++ & 0xFF;
+ (void) sprintf(pHex, "%02x", value);
+ pHex += 2;
+ }
+ return (1);
+ }
+
+ /* Return 1 if get a valid test vector. */
+ int get_test_vector(ptv)
+ test_vector *ptv;
+ {
+
+
+
+Baldwin & Rivest Informational [Page 21]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ if (1 != scanf("%d", &ptv->padding_mode))
+ return (0);
+ if (1 != scanf("%d", &ptv->rounds))
+ return (0);
+ if ((ptv->rounds < 0) || (MAX_ROUNDS < ptv->rounds))
+ return (0);
+ if (1 != scanf("%s", &ptv->keytext))
+ return (0);
+ if (1 != hex_to_bytes(ptv->keytext, ptv->key,
+ &ptv->key_length))
+ return (0);
+ if (1 != scanf("%s", &ptv->ivtext))
+ return (0);
+ if (1 != hex_to_bytes(ptv->ivtext, ptv->iv,
+ &ptv->iv_length))
+ return (0);
+ if (BLOCK_LENGTH != ptv->iv_length)
+ return (0);
+ if (1 != scanf("%s", &ptv->plaintext))
+ return (0);
+ if (1 != hex_to_bytes(ptv->plaintext, ptv->plain,
+ &ptv->plain_length))
+ return (0);
+ return (1);
+ }
+
+ void run_test (ptv)
+ test_vector *ptv;
+ {
+ rc5UserKey *pKey;
+ rc5CBCAlg *pAlg;
+ int numBytesOut;
+
+ pKey = RC5_Key_Create ();
+ RC5_Key_Set (pKey, ptv->key_length, ptv->key);
+
+ pAlg = RC5_CBC_Create (ptv->padding_mode,
+ ptv->rounds,
+ RC5_FIRST_VERSION,
+ BB,
+ ptv->iv);
+ (void) RC5_CBC_Encrypt_Init (pAlg, pKey);
+ ptv->cipher_length = 0;
+ (void) RC5_CBC_Encrypt_Update (pAlg,
+ ptv->plain_length, ptv->plain,
+ &(numBytesOut),
+ MAX_CIPHER_LENGTH - ptv->cipher_length,
+ &(ptv->cipher[ptv->cipher_length]));
+
+
+
+Baldwin & Rivest Informational [Page 22]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ ptv->cipher_length += numBytesOut;
+ (void) RC5_CBC_Encrypt_Final (pAlg,
+ &(numBytesOut),
+ MAX_CIPHER_LENGTH - ptv->cipher_length,
+ &(ptv->cipher[ptv->cipher_length]));
+ ptv->cipher_length += numBytesOut;
+ bytes_to_hex (ptv->cipher, ptv->cipher_length,
+ ptv->ciphertext);
+ RC5_Key_Destroy (pKey);
+ RC5_CBC_Destroy (pAlg);
+ }
+
+ void show_results (ptv)
+ test_vector *ptv;
+ {
+ if (ptv->padding_mode)
+ printf ("RC5_CBC_Pad ");
+ else
+ printf ("RC5_CBC ");
+ printf ("R = %2d ", ptv->rounds);
+ printf ("Key = %s ", ptv->keytext);
+ printf ("IV = %s ", ptv->ivtext);
+ printf ("P = %s ", ptv->plaintext);
+ printf ("C = %s", ptv->ciphertext);
+ printf ("\n");
+ }
+
+ int main(argc, argv)
+ int argc;
+ char *argv[];
+ {
+ test_vector tv;
+ test_vector *ptv = &tv;
+
+ show_banner();
+ while (get_test_vector(ptv)) {
+ run_test(ptv);
+ show_results(ptv);
+ }
+ return (0);
+ }
+
+
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 23]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+9.2 Test vectors
+
+ The following text is an input file to the test program presented in
+ the previous subsection. The output is given in the next subsection.
+
+ 0 00 00 0000000000000000 0000000000000000
+ 0 00 00 0000000000000000 ffffffffffffffff
+ 0 00 00 0000000000000001 0000000000000000
+ 0 00 00 0000000000000000 0000000000000001
+ 0 00 00 0102030405060708 1020304050607080
+ 0 01 11 0000000000000000 0000000000000000
+ 0 02 00 0000000000000000 0000000000000000
+ 0 02 00000000 0000000000000000 0000000000000000
+ 0 08 00 0000000000000000 0000000000000000
+ 0 08 00 0102030405060708 1020304050607080
+ 0 12 00 0102030405060708 1020304050607080
+ 0 16 00 0102030405060708 1020304050607080
+ 0 08 01020304 0000000000000000 ffffffffffffffff
+ 0 12 01020304 0000000000000000 ffffffffffffffff
+ 0 16 01020304 0000000000000000 ffffffffffffffff
+ 0 12 0102030405060708 0000000000000000 ffffffffffffffff
+ 0 08 0102030405060708 0102030405060708 1020304050607080
+ 0 12 0102030405060708 0102030405060708 1020304050607080
+ 0 16 0102030405060708 0102030405060708 1020304050607080
+ 0 08 01020304050607081020304050607080
+ 0102030405060708 1020304050607080
+ 0 12 01020304050607081020304050607080
+ 0102030405060708 1020304050607080
+ 0 16 01020304050607081020304050607080
+ 0102030405060708 1020304050607080
+
+ 0 12 0102030405 0000000000000000 ffffffffffffffff
+ 0 08 0102030405 0000000000000000 ffffffffffffffff
+ 0 08 0102030405 7875dbf6738c6478 0808080808080808
+ 1 08 0102030405 0000000000000000 ffffffffffffffff
+
+ 0 08 0102030405 0000000000000000 0000000000000000
+ 0 08 0102030405 7cb3f1df34f94811 1122334455667701
+
+ 1 08 0102030405 0000000000000000
+ ffffffffffffffff7875dbf6738c647811223344556677
+
+
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 24]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+9.3 Test results
+
+ The following text is the output produced by the test program run on
+ the inputs given in the previous subsection.
+
+ RC5 CBC Tester.
+ Each input line should contain the following
+ test parameters separated by a single space:
+ - Padding mode flag. Use 1 for RC5_CBC_Pad, else 0.
+ - Number of rounds for RC5.
+ - Key bytes in hexadecimal. Two characters per byte
+ like '01'.
+ - IV bytes in hexadecimal. Must be 16 hex characters.
+ - Plaintext bytes in hexadecimal.
+ An end of file or format error terminates the tester.
+
+ RC5_CBC R = 0 Key = 00 IV = 0000000000000000
+ P = 0000000000000000 C = 7a7bba4d79111d1e
+ RC5_CBC R = 0 Key = 00 IV = 0000000000000000
+ P = ffffffffffffffff C = 797bba4d78111d1e
+ RC5_CBC R = 0 Key = 00 IV = 0000000000000001
+ P = 0000000000000000 C = 7a7bba4d79111d1f
+ RC5_CBC R = 0 Key = 00 IV = 0000000000000000
+ P = 0000000000000001 C = 7a7bba4d79111d1f
+ RC5_CBC R = 0 Key = 00 IV = 0102030405060708
+ P = 1020304050607080 C = 8b9ded91ce7794a6
+ RC5_CBC R = 1 Key = 11 IV = 0000000000000000
+ P = 0000000000000000 C = 2f759fe7ad86a378
+ RC5_CBC R = 2 Key = 00 IV = 0000000000000000
+ P = 0000000000000000 C = dca2694bf40e0788
+ RC5_CBC R = 2 Key = 00000000 IV = 0000000000000000
+ P = 0000000000000000 C = dca2694bf40e0788
+ RC5_CBC R = 8 Key = 00 IV = 0000000000000000
+ P = 0000000000000000 C = dcfe098577eca5ff
+ RC5_CBC R = 8 Key = 00 IV = 0102030405060708
+ P = 1020304050607080 C = 9646fb77638f9ca8
+ RC5_CBC R = 12 Key = 00 IV = 0102030405060708
+ P = 1020304050607080 C = b2b3209db6594da4
+ RC5_CBC R = 16 Key = 00 IV = 0102030405060708
+ P = 1020304050607080 C = 545f7f32a5fc3836
+ RC5_CBC R = 8 Key = 01020304 IV = 0000000000000000
+ P = ffffffffffffffff C = 8285e7c1b5bc7402
+ RC5_CBC R = 12 Key = 01020304 IV = 0000000000000000
+ P = ffffffffffffffff C = fc586f92f7080934
+ RC5_CBC R = 16 Key = 01020304 IV = 0000000000000000
+ P = ffffffffffffffff C = cf270ef9717ff7c4
+ RC5_CBC R = 12 Key = 0102030405060708 IV = 0000000000000000
+ P = ffffffffffffffff C = e493f1c1bb4d6e8c
+
+
+
+Baldwin & Rivest Informational [Page 25]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ RC5_CBC R = 8 Key = 0102030405060708 IV = 0102030405060708
+ P = 1020304050607080 C = 5c4c041e0f217ac3
+ RC5_CBC R = 12 Key = 0102030405060708 IV = 0102030405060708
+ P = 1020304050607080 C = 921f12485373b4f7
+ RC5_CBC R = 16 Key = 0102030405060708 IV = 0102030405060708
+ P = 1020304050607080 C = 5ba0ca6bbe7f5fad
+ RC5_CBC R = 8 Key = 01020304050607081020304050607080
+ IV = 0102030405060708
+ P = 1020304050607080 C = c533771cd0110e63
+ RC5_CBC R = 12 Key = 01020304050607081020304050607080
+ IV = 0102030405060708
+ P = 1020304050607080 C = 294ddb46b3278d60
+ RC5_CBC R = 16 Key = 01020304050607081020304050607080
+ IV = 0102030405060708
+ P = 1020304050607080 C = dad6bda9dfe8f7e8
+ RC5_CBC R = 12 Key = 0102030405 IV = 0000000000000000
+ P = ffffffffffffffff C = 97e0787837ed317f
+ RC5_CBC R = 8 Key = 0102030405 IV = 0000000000000000
+ P = ffffffffffffffff C = 7875dbf6738c6478
+ RC5_CBC R = 8 Key = 0102030405 IV = 7875dbf6738c6478
+ P = 0808080808080808 C = 8f34c3c681c99695
+ RC5_CBC_Pad R = 8 Key = 0102030405 IV = 0000000000000000
+ P = ffffffffffffffff C = 7875dbf6738c64788f34c3c681c99695
+ RC5_CBC R = 8 Key = 0102030405 IV = 0000000000000000
+ P = 0000000000000000 C = 7cb3f1df34f94811
+ RC5_CBC R = 8 Key = 0102030405 IV = 7cb3f1df34f94811
+ P = 1122334455667701 C = 7fd1a023a5bba217
+ RC5_CBC_Pad R = 8 Key = 0102030405 IV = 0000000000000000
+ P = ffffffffffffffff7875dbf6738c647811223344556677
+ C = 7875dbf6738c64787cb3f1df34f948117fd1a023a5bba217
+
+10. Security Considerations
+
+ The RC5 cipher is relatively new so critical reviews are still being
+ performed. However, the cipher's simple structure makes it easy to
+ analyze and hopefully easier to assess its strength. Reviews so far
+ are very promising.
+
+ Early results [1] suggest that for RC5 with a 64 bit block size (32
+ bit word size), 12 rounds will suffice to resist linear and
+ differential cyptanalysis. The 128 bit block version has not been
+ studied as much as the 64 bit version, but it appears that 16 rounds
+ would be an appropriate minimum. Block sizes less than 64 bits are
+ academically interesting but should not be used for cryptographic
+ security. Greater security can be achieved by increasing the number
+ of rounds at the cost of decreasing the throughput of the cipher.
+
+
+
+
+
+Baldwin & Rivest Informational [Page 26]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ The length of the secret key helps determine the cipher's resistance
+ to brute force key searching attacks. A key length of 128 bits
+ should give adequate protection against brute force key searching by
+ a well funded opponent for a couple decades [7]. For RC5 with 12
+ rounds, the key setup time and data encryption time are the same for
+ all key lengths less than 832 bits, so there is no performance reason
+ for choosing short keys. For larger keys, the key expansion step
+ will run slower because the user key table, L, will be longer than
+ the expanded key table, S. However, the encryption time will be
+ unchanged since it is only a function of the number of rounds.
+
+ To comply with export regulations it may be necessary to choose keys
+ that only have 40 unknown bits. A poor way to do this would be to
+ choose a simple 5 byte key. This should be avoided because it would
+ be easy for an opponent to pre-compute key searching information.
+ Another common mechanism is to pick a 128 bit key and publish the
+ first 88 bits. This method reveals a large number of the entries in
+ the user key table, L, and the question of whether RC5 key expansion
+ provides adequate security in this situation has not been studied,
+ though it may be fine. A conservative way to conform to a 40 bit
+ limitation is to pick a seed value of 128 bits, publish 88 bits of
+ this seed, run the entire seed through a hash function like MD5 [4],
+ and use the 128 bit output of the hash function as the RC5 key.
+
+ In the case of 40 unknown key bits with 88 known key bits (i.e., 88
+ salt bits) there should still be 12 or more rounds for the 64 bit
+ block version of RC5, otherwise the value of adding salt bits to the
+ key is likely to be lost.
+
+ The lifetime of the key also influences security. For high security
+ applications, the key to any 64 bit block cipher should be changed
+ after encrypting 2**32 blocks (2**64 blocks for a 128 bit block
+ cipher). This helps to guard against linear and differential
+ cryptanalysis. For the case of 64 bit blocks, this rule would
+ recommend changing the key after 2**40 (i.e. 10**12) bytes are
+ encrypted. See Schneier [6] page 183 for further discussion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 27]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+11. ASN.1 Identifiers
+
+ For applications that use ASN.1 descriptions, it is necessary to
+ define the algorithm identifier for these ciphers along with their
+ parameter block formats. The ASN.1 definition of an algorithm
+ identifier already exists and is listed below for reference.
+
+ AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL
+ }
+
+ The values for the algorithm field are:
+
+ RC5_CBC OBJECT IDENTIFIER ::=
+ { iso (1) member-body (2) US (840) rsadsi (113549)
+ encryptionAlgorithm (3) RC5CBC (8) }
+
+ RC5_CBC_Pad OBJECT IDENTIFIER ::=
+ { iso (1) member-body (2) US (840) rsadsi (113549)
+ encryptionAlgorithm (3) RC5CBCPAD (9) }
+
+ The structure of the parameters field for these algorithms is given
+ below. NOTE: if the iv field is not included, then the
+ initialization vector defaults to a block of zeros whose size depends
+ on the blockSizeInBits field.
+
+ RC5_CBC_Parameters ::= SEQUENCE {
+ version INTEGER (v1_0(16)),
+ rounds INTEGER (8..127),
+ blockSizeInBits INTEGER (64, 128),
+ iv OCTET STRING OPTIONAL
+ }
+
+References
+
+ [1] Kaliski, Burton S., and Yinqun Lisa Yin, "On Differential and
+ Linear Cryptanalysis of the RC5 Encryption Algorithm", In Advances
+ in Cryptology - Crypto '95, pages 171-184, Springer-Verlag, New
+ York, 1995.
+
+ [2] Rivest, Ronald L., "The RC5 Encryption Algorithm", In
+ Proceedings of the Second International Workshop on Fast Software
+ Encryption, pages 86-96, Leuven Belgium, December 1994.
+
+ [3] Rivest, Ronald L., "RC5 Encryption Algorithm", In Dr. Dobbs
+ Journal, number 226, pages 146-148, January 1995.
+
+
+
+
+Baldwin & Rivest Informational [Page 28]
+
+RFC 2040 RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS October 1996
+
+
+ [4] Rivest, Ronald L., "The MD5 Message-Digest Algorithm", RFC
+ 1321.
+
+ [5] RSA Laboratories, "Public Key Cryptography Standards (PKCS)",
+ RSA Data Security Inc. See ftp.rsa.com.
+
+ [6] Schneier, Bruce, "Applied Cryptography", Second Edition, John
+ Wiley and Sons, New York, 1996. Errata: on page 195, line 13, the
+ reference number should be [402].
+
+ [7] Business Software Alliance, Matt Blaze et al., "Minimum Key
+ Length for Symmetric Ciphers to Provide Adequate Commercial
+ Security", http://www.bsa.org/bsa/cryptologists.html.
+
+ [8] RSA Data Security Inc., "RC5 Reference Code in C", See the web
+ site: www.rsa.com, for availability. Not available with the first
+ draft of this document.
+
+Authors' Addresses
+
+ Robert W. Baldwin
+ RSA Data Security, Inc.
+ 100 Marine Parkway
+ Redwood City, CA 94065
+
+ Phone: (415) 595-8782
+ Fax: (415) 595-1873
+ EMail: baldwin@rsa.com, or baldwin@lcs.mit.edu
+
+
+ Ronald L. Rivest
+ Massachusetts Institute of Technology
+ Laboratory for Computer Science
+ NE43-324
+ 545 Technology Square
+ Cambridge, MA 02139-1986
+
+ Phone: (617) 253-5880
+ EMail: rivest@theory.lcs.mit.edu
+
+
+
+
+
+
+
+
+
+
+
+
+Baldwin & Rivest Informational [Page 29]
+