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

📄 cfbimpl.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
字号:
/* Copyright 2003-2004, Voltage Security, all rights reserved.
 */
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "cipher.h"
#include "block.h"
#include "cfb.h"
#include "errorctx.h"

int CFBEncryptInit (
   VoltAlgorithmObject *algObj,
   VoltKeyObject *keyObj
   )
{
  int status;
  VoltLibCtx *libCtx = (VoltLibCtx *)(algObj->voltObject.libraryCtx);
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Copy the initVector.
     */
    Z2Memcpy (
      cfbCtx->currentVector, cfbCtx->feedCtx.initVector,
      cfbCtx->feedCtx.blockSize);
    cfbCtx->xorUsed = cfbCtx->feedCtx.blockSize;

    /* Call the underlying algorithm's Init.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = cfbCtx->AlgEncryptInit (algObj, keyObj);

  } while (0);

  VOLT_LOG_ERROR_COMPARE (
    status, algObj->voltObject.libraryCtx, status, 0, fnctLine,
    "CFBEncryptInit", (char *)0)

  return (status);
}

int CFBEncryptUpdateBlock (
   VoltAlgorithmObject *algObj,
   VtRandomObject random,
   unsigned char *dataToEncrypt,
   unsigned int dataToEncryptLen,
   unsigned char *encryptedData
   )
{
  unsigned int index, dataLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(algObj->voltObject.libraryCtx);
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);

  /* If we have some unused bits in the XOR vector, use them.
   */
  if (cfbCtx->xorUsed < cfbCtx->feedCtx.blockSize)
  {
    /* Are there enough dataToEncrypt bytes to finish out the block of
     * XOR bytes we have available?
     */
    dataLen = cfbCtx->feedCtx.blockSize - cfbCtx->xorUsed;
    if (dataToEncryptLen < dataLen)
      dataLen = dataToEncryptLen;
    for (index = cfbCtx->xorUsed; index < (cfbCtx->xorUsed + dataLen) ; ++index)
    {
      /* Encrypted data is the input XOR'd with a byte from the XOR
       * vector.
       */
      *encryptedData = *dataToEncrypt ^ cfbCtx->feedCtx.xorVector[index];
      /* The ciphertext will be used to generate the next XOR vector,
       * so save it.
       */
      cfbCtx->currentVector[index] = *encryptedData;
      dataToEncrypt++;
      encryptedData++;
    }
    dataToEncryptLen -= dataLen;
    cfbCtx->xorUsed += dataLen;
  }

  /* So long as we have blocks, operate on them.
   */
  while (dataToEncryptLen >= cfbCtx->feedCtx.blockSize)
  {
    /* Encrypt the currentVector to get the XOR vector.
     */
    cfbCtx->AlgEncryptUpdate (
      algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
      cfbCtx->feedCtx.xorVector);

    /* XOR each byte of input with the XOR vector. This will be the
     * ciphertext, which is also the next vector to encrypt.
     */
    for (index = 0; index < cfbCtx->feedCtx.blockSize; ++index)
    {
      cfbCtx->currentVector[index] =
        cfbCtx->feedCtx.xorVector[index] ^ dataToEncrypt[index];
    }

    /* Copy the data to the output buffer.
     */
    Z2Memcpy (encryptedData, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize);
    dataToEncrypt += cfbCtx->feedCtx.blockSize;
    encryptedData += cfbCtx->feedCtx.blockSize;
    dataToEncryptLen -= cfbCtx->feedCtx.blockSize;
  }

  /* After processing full blocks, if there's no more input, we're done.
   */
  if (dataToEncryptLen == 0)
    return (0);

  /* We have some leftovers, create the XOR vector.
   */
  cfbCtx->AlgEncryptUpdate (
    algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
    cfbCtx->feedCtx.xorVector);

  for (index = 0; index < dataToEncryptLen; ++index)
  {
    encryptedData[index] =
      dataToEncrypt[index] ^ cfbCtx->feedCtx.xorVector[index];
    /* The ciphertext will be used to generate the next XOR vector,
     * so save it.
     */
    cfbCtx->currentVector[index] = encryptedData[index];
  }
  cfbCtx->xorUsed = dataToEncryptLen;

  return (0);
}

int CFBEncryptUpdate1Bit (
   VoltAlgorithmObject *algObj,
   VtRandomObject random,
   unsigned char *dataToEncrypt,
   unsigned int dataToEncryptLen,
   unsigned char *encryptedData
   )
{
  int index;
  unsigned int shiftCount;
  unsigned char xorBit, nextBit, saveBit, mask;
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);

  while (dataToEncryptLen > 0)
  {
    /* For one byte of input, do 8 1-bit XOR's.
     */
    mask = 0x80;
    *encryptedData = *dataToEncrypt;
    for (shiftCount = 0; shiftCount < 8; ++shiftCount)
    {
      /* Create a bit of XOR, it is the most significant bit of the XOR
       * vector (after encrypting the currentVector).
       */
      cfbCtx->AlgEncryptUpdate (
        algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
        cfbCtx->feedCtx.xorVector);
      xorBit = (cfbCtx->feedCtx.xorVector[0] & 0x80) >> shiftCount;
      /* XOR the plaintext with the XOR bit.
       */
      *encryptedData ^= xorBit;
      /* Capture the resulting bit to update the vectors.
       */
      xorBit = *encryptedData & mask;
      /* Shift that bit to the low order position.
       */
      nextBit = xorBit >> (7 - shiftCount);
      /* Shift the currentVector left 1 bit.
       */
      for (index = (int)(cfbCtx->feedCtx.blockSize) - 1; index >= 0; --index)
      {
        saveBit = cfbCtx->currentVector[index] >> 7;
        cfbCtx->currentVector[index] <<= 1;
        cfbCtx->currentVector[index] |= nextBit;
        nextBit = saveBit;
      }

      mask >>= 1;
    }

    dataToEncryptLen--;
    dataToEncrypt++;
    encryptedData++;
  }

  return (0);
}

int CFBEncryptUpdate8Bit (
   VoltAlgorithmObject *algObj,
   VtRandomObject random,
   unsigned char *dataToEncrypt,
   unsigned int dataToEncryptLen,
   unsigned char *encryptedData
   )
{
  unsigned int index;
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);

  while (dataToEncryptLen > 0)
  {
    /* Create a byte of XOR, it is the most significant byte of the XOR
     * vector (after encrypting the currentVector).
     */
    cfbCtx->AlgEncryptUpdate (
      algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
      cfbCtx->feedCtx.xorVector);
    /* XOR the plaintext with the XOR byte.
     */
    *encryptedData = *dataToEncrypt ^ cfbCtx->feedCtx.xorVector[0];
    /* Shift the currentVector left 1 byte.
     */
    for (index = 0; index < cfbCtx->feedCtx.blockSize - 1; ++index)
      cfbCtx->currentVector[index] = cfbCtx->currentVector[index + 1];
    /* The new low order byte of the currentVector is the encrypted
     * byte.
     */
    cfbCtx->currentVector[cfbCtx->feedCtx.blockSize - 1] = *encryptedData;

    dataToEncryptLen--;
    dataToEncrypt++;
    encryptedData++;
  }

  return (0);
}

int CFBDecryptUpdateBlock (
   VoltAlgorithmObject *algObj,
   VtRandomObject random,
   unsigned char *dataToDecrypt,
   unsigned int dataToDecryptLen,
   unsigned char *decryptedData
   )
{
  unsigned int index, dataLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(algObj->voltObject.libraryCtx);
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);

  /* If we have some unused bits in the XOR vector, use them.
   */
  if (cfbCtx->xorUsed < cfbCtx->feedCtx.blockSize)
  {
    /* Are there enough dataToDecrypt bytes to finish out the block of
     * XOR bytes we have available?
     */
    dataLen = cfbCtx->feedCtx.blockSize - cfbCtx->xorUsed;
    if (dataToDecryptLen < dataLen)
      dataLen = dataToDecryptLen;
    for (index = cfbCtx->xorUsed; index < (cfbCtx->xorUsed + dataLen) ; ++index)
    {
      /* The ciphertext will be used to generate the next XOR vector,
       * so save it.
       */
      cfbCtx->currentVector[index] = *dataToDecrypt;

      /* Decrypted data is the input XOR'd with a byte from the XOR
       * vector.
       */
      *decryptedData = *dataToDecrypt ^ cfbCtx->feedCtx.xorVector[index];
      dataToDecrypt++;
      decryptedData++;
    }
    dataToDecryptLen -= dataLen;
    cfbCtx->xorUsed += dataLen;
  }

  /* So long as we have blocks, operate on them.
   */
  while (dataToDecryptLen >= cfbCtx->feedCtx.blockSize)
  {
    /* Encrypt the currentVector to get the XOR vector.
     */
    cfbCtx->AlgEncryptUpdate (
      algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
      cfbCtx->feedCtx.xorVector);

    /* The current ciphertext is the next block's data to encrypt.
     */
    Z2Memcpy (
      cfbCtx->currentVector, dataToDecrypt, cfbCtx->feedCtx.blockSize);

    /* XOR each byte of input with the XOR vector. This will be the
     * recovered text.
     */
    for (index = 0; index < cfbCtx->feedCtx.blockSize; ++index)
      decryptedData[index] =
        cfbCtx->feedCtx.xorVector[index] ^ dataToDecrypt[index];

    dataToDecrypt += cfbCtx->feedCtx.blockSize;
    decryptedData += cfbCtx->feedCtx.blockSize;
    dataToDecryptLen -= cfbCtx->feedCtx.blockSize;
  }

  /* After processing full blocks, if there's no more input, we're done.
   */
  if (dataToDecryptLen == 0)
    return (0);

  /* We have some leftovers, create the XOR vector.
   */
  cfbCtx->AlgEncryptUpdate (
    algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
    cfbCtx->feedCtx.xorVector);

  for (index = 0; index < dataToDecryptLen; ++index)
  {
    /* The ciphertext will be used to generate the next XOR vector,
     * so save it.
     */
    cfbCtx->currentVector[index] = dataToDecrypt[index];
    decryptedData[index] =
      dataToDecrypt[index] ^ cfbCtx->feedCtx.xorVector[index];
  }
  cfbCtx->xorUsed = dataToDecryptLen;

  return (0);
}

int CFBDecryptUpdate1Bit (
   VoltAlgorithmObject *algObj,
   VtRandomObject random,
   unsigned char *dataToDecrypt,
   unsigned int dataToDecryptLen,
   unsigned char *decryptedData
   )
{
  int index;
  unsigned int shiftCount;
  unsigned char xorBit, nextBit, saveBit, mask;
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);

  while (dataToDecryptLen > 0)
  {
    /* For one byte of input, do 8 1-bit XOR's.
     */
    mask = 0x80;
    *decryptedData = *dataToDecrypt;
    for (shiftCount = 0; shiftCount < 8; ++shiftCount)
    {
      /* Save the current bit of ciphertext for the currentVector.
       */
      nextBit = *decryptedData & mask;
      nextBit >>= (7 - shiftCount);
      /* Create a bit of XOR, it is the most significant bit of the XOR
       * vector (after encrypting the currentVector).
       */
      cfbCtx->AlgEncryptUpdate (
        algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
        cfbCtx->feedCtx.xorVector);
      xorBit = (cfbCtx->feedCtx.xorVector[0] & 0x80) >> shiftCount;
      /* XOR the ciphertext with the XOR bit.
       */
      *decryptedData ^= xorBit;
      /* Shift the currentVector left 1 bit.
       */
      for (index = (int)(cfbCtx->feedCtx.blockSize) - 1; index >= 0; --index)
      {
        saveBit = cfbCtx->currentVector[index] >> 7;
        cfbCtx->currentVector[index] <<= 1;
        cfbCtx->currentVector[index] |= nextBit;
        nextBit = saveBit;
      }

      mask >>= 1;
    }

    dataToDecryptLen--;
    dataToDecrypt++;
    decryptedData++;
  }

  return (0);
}

int CFBDecryptUpdate8Bit (
   VoltAlgorithmObject *algObj,
   VtRandomObject random,
   unsigned char *dataToDecrypt,
   unsigned int dataToDecryptLen,
   unsigned char *decryptedData
   )
{
  unsigned int index;
  unsigned char saveByte;
  VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
  VoltBlockCipherCtx *blockCtx =
    (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
  VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);

  while (dataToDecryptLen > 0)
  {
    /* Save the current byte of ciphertext for the currentVector.
     */
    saveByte = *dataToDecrypt;
    /* Create a byte of XOR, it is the most significant byte of the XOR
     * vector (after encrypting the currentVector).
     */
    cfbCtx->AlgEncryptUpdate (
      algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
      cfbCtx->feedCtx.xorVector);
    /* XOR the ciphertext with the XOR byte.
     */
    *decryptedData = cfbCtx->feedCtx.xorVector[0] ^ *dataToDecrypt;
    /* Shift the currentVector left 1 byte.
     */
    for (index = 0; index < cfbCtx->feedCtx.blockSize - 1; ++index)
      cfbCtx->currentVector[index] = cfbCtx->currentVector[index + 1];
    /* The new low order byte of the currentVector is the encrypted
     * byte.
     */
    cfbCtx->currentVector[cfbCtx->feedCtx.blockSize - 1] = saveByte;

    dataToDecryptLen--;
    dataToDecrypt++;
    decryptedData++;
  }

  return (0);
}

⌨️ 快捷键说明

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