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

📄 p1t2pad.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2005-2006, Voltage Security, all rights reserved.
 */
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "cipher.h"
#include "p1pad.h"
#include "errorctx.h"

int VtPaddingPkcs1Type2 (
   VtAlgorithmObject object,
   VtPaddingInfo *info,
   unsigned int flag
   )
{
  int status;
  VoltAlgorithmObject *obj = (VoltAlgorithmObject *)object;
  VoltCipherClassCtx *cipherCtx;
  VoltPaddingInfo *padInfo = (VoltPaddingInfo *)info;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Check the flag, it should be VOLT_PADDING_SET_TYPE_FLAG.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_TYPE;
    if (flag != VOLT_PADDING_SET_TYPE_FLAG)
      break;

    /* The associated info should be a NULL pointer.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ASSOCIATED_INFO;
    if (padInfo->info != (Pointer)0)
      break;

    /* Check the class of the object. It should be
     * VOLT_CLASS_ASYMMETRIC_CIPHER.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_SET;
    if (obj->algClass != VOLT_CLASS_ASYMMETRIC_CIPHER)
      break;

    /* We have an asymmetric cipher object, which means we have a
     * CipherCtx.
     */
    cipherCtx = (VoltCipherClassCtx *)(obj->classCtx);

    /* This only works with RSA.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if (cipherCtx->setState != VOLT_CIPHER_SET_STATE_RSA)
      break;

    cipherCtx->Pad = P1T2Pad;
    cipherCtx->Unpad = P1T2Unpad;

    obj->subAlg2 |= VOLT_SUB_ALG_P1_T2_PAD;

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "VtPaddingPkcs1Type2", fnctLine, (char *)0)

  return (status);
}

int P1T2Pad (
   VoltAlgorithmObject *obj,
   VtRandomObject random,
   Pointer ctx,
   unsigned char *block,
   unsigned int inputLen,
   unsigned int blockSize
   )
{
  int status;
  unsigned int ffLen, offset;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VtRandomObject randomToUse;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* If there's no random object, get one from the libCtx.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NO_RANDOM_OBJECT;
    randomToUse = random;
    if (random == (VtRandomObject)0)
    {
      randomToUse = (VtRandomObject)VoltGetLibCtxInfo (
        (VtLibCtx)libCtx, VOLT_LIB_CTX_INFO_TYPE_RANDOM);

      if (randomToUse == (VtRandomObject)0)
        break;
    }

    /* Make sure the random object is valid.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_RANDOM_OBJ;
    if (VOLT_OBJECT_TYPE_NOT_EQUAL (randomToUse, VOLT_OBJECT_TYPE_RANDOM))
      break;

    /* P1 Type 2 padding looks like this
     *   00 01 <random, non-zero bytes> 00 <data to encrypt>
     * There must be at least 8 octets of random bytes.
     * How long will the random bytess be?
     * First, count the number of bytes that will make up everything
     * else, make sure that's not longer than blockSize.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    ffLen = 3 + inputLen;
    if (ffLen > blockSize)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    ffLen = blockSize - ffLen;
    if (ffLen < 8)
      break;

    /* Move the data to encrypt to the end of the block.
     */
    offset = blockSize - inputLen;
    Z2Memmove (block + offset, block, inputLen);

    /* The byte right before the data to encrypt is 00.
     */
    block[offset - 1] = 0;

    /* The first byte is 00, the next byte is 02.
     */
    block[0] = 0;
    block[1] = 2;

    /* The rest of the bytes are random bytes
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGenerateRandomBytes (randomToUse, block + 2, ffLen);
    if (status != 0)
      break;

    /* Make sure all the bytes are non-zero.
     */
    offset = 2;
    do
    {
      /* If the value is not zero, just move on to the next byte,
       * unless this was the last byte.
       */
      if (block[offset] != 0)
      {
        if (ffLen == 1)
          break;

        ffLen--;
        offset++;
        continue;
      }

      /* The byte is 00, generate a new one.
       */
      status = VtGenerateRandomBytes (randomToUse, block + offset, 1);
      if (status != 0)
        break;

    } while (1);

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, errorType,
    (char *)0, "P1T1Pad", fnctLine, (char *)0)

  return (status);
}

int P1T2Unpad (
   VoltAlgorithmObject *obj,
   Pointer ctx,
   unsigned char *block,
   unsigned int blockSize,
   unsigned int *outputLen
   )
{
  int status;
  unsigned int index, ffLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* To help avoid timing attacks, perform all checks.
     */
    status = 0;
    if ( (block[0] != 0) || (block[1] != 2) )
      status = VT_ERROR_INVALID_PAD;

    /* Keep checking bytes until we find the next 00 byte.
     */
    index = 2;
    ffLen = 0;
    do
    {
      if ( (block[index] == 0) && (ffLen == 0) )
        ffLen = index - 2;
      index++;
    } while (index < blockSize);

    /* There must be at least 8 pad bytes.
     */
    if (ffLen < 8)
      status = VT_ERROR_INVALID_PAD;

    /* Move the message block to the front.
     */
    ffLen += 3;
    Z2Memmove (block, block + ffLen, blockSize - ffLen);
    *outputLen = blockSize - ffLen;

  } while (0);

  VOLT_SET_FNCT_LINE (fnctLine)
  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "P1T1Unpad", fnctLine, (char *)0)

  return (status);
}

⌨️ 快捷键说明

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