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

📄 p1t1pad.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 "sign.h"
#include "p1pad.h"
#include "errorctx.h"

/* Based on the digestAlg, return a buffer containing the digestInfo.
 * <p>This function will allocate the memory to hold the digestInfo,
 * the caller must free that memory.
 * <p>The function will also return the length the digest should be.
 * <p>This routine will do no error checking, it is the responsibility
 * of the caller not to make mistakes.
 */
static int VOLT_CALLING_CONV GetDigestInfoAlloc VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   unsigned int digestAlg,
   unsigned char **digestInfo,
   unsigned int *digestInfoLen,
   unsigned int *digestLen
));

int VtPaddingPkcs1Type1 (
   VtAlgorithmObject object,
   VtPaddingInfo *info,
   unsigned int flag
   )
{
  int status;
  VoltAlgorithmObject *obj = (VoltAlgorithmObject *)object;
  VoltSignClassCtx *signCtx;
  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_SIGNATURE
     * or VOLT_CLASS_VERIFY.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_SET;
    if ((obj->algClass & (VOLT_CLASS_SIGNATURE | VOLT_CLASS_VERIFY)) == 0)
      break;

    /* We have a signature object, which means we have a SignCtx.
     */
    signCtx = (VoltSignClassCtx *)(obj->classCtx);

    /* This only works with RSA.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ((signCtx->algorithm & VOLT_SIGNATURE_ALG_RSA) == 0)
      break;

    signCtx->Pad = P1T1Pad;
    signCtx->Unpad = P1T1Unpad;

    obj->subAlg2 |= VOLT_SUB_ALG_P1_T1_PAD;

    status = 0;

  } while (0);

  /* If something went wrong, indicate that this object is not usable.
   */
  if (status != 0)
    obj->state = VOLT_STATE_ERROR;

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

  return (status);
}

int P1T1Pad (
   VoltAlgorithmObject *obj,
   VtRandomObject random,
   Pointer ctx,
   unsigned char *block,
   unsigned int inputLen,
   unsigned int blockSize
   )
{
  int status;
  unsigned int ffLen, offset, digestInfoLen, digestLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  unsigned char *digestInfo = (unsigned char *)0;
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = GetDigestInfoAlloc (
      libCtx, signCtx->digestAlg, &digestInfo, &digestInfoLen, &digestLen);
    if (status != 0)
      break;

    /* Make sure the inputLen is the digest length.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (inputLen != digestLen)
      break;

    /* P1 Type 1 padding looks like this
     *   00 01 ff ff ... ff 00 <digestInfo> <digest>
     * There must be at least 8 octets of ff.
     * How long will the ff's 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)
    ffLen = digestInfoLen + digestLen + 3;
    if (ffLen > blockSize)
      break;

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

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

    /* Copy the digestInfo.
     */
    offset -= digestInfoLen;
    Z2Memcpy (block + offset, digestInfo, digestInfoLen);

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

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

    /* The rest of the bytes are 0xff
     */
    Z2Memset (block + 2, 0xff, ffLen);

    status = 0;

  } while (0);

  if (digestInfo != (unsigned char *)0)
    Z2Free (digestInfo);

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

  return (status);
}

int P1T1Unpad (
   VoltAlgorithmObject *obj,
   Pointer ctx,
   unsigned char *block,
   unsigned int blockSize,
   unsigned int *outputLen
   )
{
  int status;
  unsigned int index, ffLen, digestInfoLen, digestLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  unsigned char *digestInfo = (unsigned char *)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = GetDigestInfoAlloc (
      libCtx, signCtx->digestAlg, &digestInfo, &digestInfoLen, &digestLen);
    if (status != 0)
      break;

    /* How many 0xff bytes should there be? While we're computing that,
     * make sure blockLen is reasonable.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    ffLen = digestInfoLen + digestLen + 3;
    if (ffLen > blockSize)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    /* The next section of code is going to check the pad bytes. If
     * they're wrong, we'll set status to an error, but we'll continue
     * the check. After the checks, we'll move the digest to the front
     * (the Unpad). This way, we can return an error if there is an
     * error, but still return the digest, in case the caller wants to
     * ignore the error.
     */
    status = 0;

    /* PKCS #1 says there must be at leas 8 ff bytes.
     */
    ffLen = blockSize - ffLen;
    if (ffLen < 8)
      status = VT_ERROR_INVALID_PAD;

    /* The first two bytes must be 00 01.
     */
    if ( (block[0] != 0) || (block[1] != 1) )
      status = VT_ERROR_INVALID_PAD;

    /* The next ffLen bytes should be 0xff.
     */
    for (index = 2; index < ffLen + 2; ++index)
      if (block[index] != 0xff)
        break;

    /* If we broke early, there was an error.
     */
    if (index < (ffLen + 2))
      status = VT_ERROR_INVALID_PAD;

    /* The next byte should be 00.
     */
    if (block[ffLen + 2] != 0)
      status = VT_ERROR_INVALID_PAD;

    /* The next padCtx->digestInfoLen bytes should be the digestInfo.
     */
    if (Z2Memcmp (
      block + ffLen + 3, digestInfo, digestInfoLen) != 0)
      status = VT_ERROR_INVALID_PAD;

    /* Move the digest to the front.
     */
    Z2Memmove (
      block, block + ffLen + 3 + digestInfoLen, digestLen);

    *outputLen = digestLen;

  } while (0);

  if (digestInfo != (unsigned char *)0)
    Z2Free (digestInfo);

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

  return (status);
}

static int GetDigestInfoAlloc (
   VoltLibCtx *libCtx,
   unsigned int digestAlg,
   unsigned char **digestInfo,
   unsigned int *digestInfoLen,
   unsigned int *digestLen
   )
{
  int status;
  unsigned int infoLen;
  unsigned char *info;
  unsigned char *buffer = (unsigned char *)0;
  unsigned char md5Info[VOLT_MD5_DIGEST_INFO_LEN] =
    { VOLT_MD5_DIGEST_INFO };
  unsigned char sha1Info[VOLT_SHA1_DIGEST_INFO_LEN] =
    { VOLT_SHA1_DIGEST_INFO };
  unsigned char sha224Info[VOLT_SHA224_DIGEST_INFO_LEN] =
    { VOLT_SHA224_DIGEST_INFO };
  unsigned char sha256Info[VOLT_SHA256_DIGEST_INFO_LEN] =
    { VOLT_SHA256_DIGEST_INFO };
  unsigned char sha384Info[VOLT_SHA384_DIGEST_INFO_LEN] =
    { VOLT_SHA384_DIGEST_INFO };
  unsigned char sha512Info[VOLT_SHA512_DIGEST_INFO_LEN] =
    { VOLT_SHA512_DIGEST_INFO };
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  status = 0;
  switch (digestAlg)
  {
    case VT_DIGEST_ALG_MD5:
      info = md5Info;
      infoLen = VOLT_MD5_DIGEST_INFO_LEN;
      *digestLen = 16;
      break;

    case VT_DIGEST_ALG_SHA1:
      info = sha1Info;
      infoLen = VOLT_SHA1_DIGEST_INFO_LEN;
      *digestLen = 20;
      break;

    case VT_DIGEST_ALG_SHA224:
      info = sha224Info;
      infoLen = VOLT_SHA224_DIGEST_INFO_LEN;
      *digestLen = 28;
      break;

    case VT_DIGEST_ALG_SHA256:
      info = sha256Info;
      infoLen = VOLT_SHA256_DIGEST_INFO_LEN;
      *digestLen = 32;
      break;

    case VT_DIGEST_ALG_SHA384:
      info = sha384Info;
      infoLen = VOLT_SHA384_DIGEST_INFO_LEN;
      *digestLen = 48;
      break;

    case VT_DIGEST_ALG_SHA512:
      info = sha512Info;
      infoLen = VOLT_SHA512_DIGEST_INFO_LEN;
      *digestLen = 64;
      break;

    default:
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT;
  }

  /* If we have a supported digest, allocate the buffer to hold the
   * digestInfo and copy the data.
   */
  if (status == 0)
  {
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    buffer = (unsigned char *)Z2Malloc (infoLen, 0);
    if (buffer != (unsigned char *)0)
    {
      Z2Memcpy (buffer, info, infoLen);
      *digestInfo = buffer;
      *digestInfoLen = infoLen;
      return (0);
    }
  }

  /* If we reach this point in the code, there was an error.
   */
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

  VOLT_LOG_ERROR_INFO (
    libCtx, 0, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "GetDigestInfoAlloc", fnctLine, (char *)0)

  return (status);
}

⌨️ 快捷键说明

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