⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfc2040.txt

📁 中、英文RFC文档大全打包下载完全版 .
💻 TXT
📖 第 1 页 / 共 4 页
字号:
  /* 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 19966.  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 19966.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 asBaldwin & 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));  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -