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

📄 rfc2040.txt

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

⌨️ 快捷键说明

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