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

📄 rsax931impl.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 "rsa.h"
#include "rsax931.h"
#include "mpint.h"
#include "errorctx.h"

int X931Pad (
   VoltAlgorithmObject *obj,
   VtRandomObject random,
   Pointer padCtx,
   unsigned char *block,
   unsigned int inputLen,
   unsigned int blockSize
   )
{
  int status;
  unsigned int bbLen, digestLen, x931Byte;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* How long is the input supposed to be?
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltGetDigestLenFromAlg (
      libCtx, signCtx->digestAlg, &digestLen, &x931Byte);
    if (status != 0)
      break;

    /* If the x931Byte is 0, this is an unsupported digest algorithm.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    if (x931Byte == 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (inputLen != digestLen)
      break;

    /* X9.31 padding looks like this.
     *   6B BB ... BB BA <digest> <digestByte> CC
     * If the digest is so big that there's no room for the BB bytes,
     * that's OK, but there must be room for the 6B, BA, digestByte and
     * CC. The digestByte is an identitfier byte, 0x33 means SHA-1, etc.
     * How long will the BB'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)
    bbLen = digestLen + 4;
    if (bbLen > blockSize)
      break;

    bbLen = blockSize - bbLen;

    /* Move the digest to the end (except for the two trailing bits).
     */
    Z2Memmove (block + blockSize - (digestLen + 2), block, digestLen);

    /* The next byte is the digestByte.
     */
    block[blockSize - 2] = (unsigned char)x931Byte;
    /* The last byte is 0xcc.
     */
    block[blockSize - 1] = 0xcc;

    /* The first byte is 0x6b
     */
    block[0] = 0x6b;

    /* The next bbLen bytes are 0xbb.
     */
    Z2Memset (block + 1, 0xbb, bbLen);

    /* The byte after the bb's (the byte before the digest) is 0xba.
     */
    block[bbLen + 1] = 0xba;

    status = 0;

  } while (0);

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

  return (status);
}

int X931Unpad (
   VoltAlgorithmObject *obj,
   Pointer padCtx,
   unsigned char *block,
   unsigned int blockSize,
   unsigned int *outputLen
   )
{
  int status;
  unsigned int index, bbLen, digestLen, x931Byte;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  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 = VoltGetDigestLenFromAlg (
      libCtx, signCtx->digestAlg, &digestLen, &x931Byte);
    if (status != 0)
      break;

    /* If the x931Byte is 0, this is an unsupported digest algorithm.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    if (x931Byte == 0)
      break;

    /* How many 0xbb 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;
    bbLen = digestLen + 4;
    if (bbLen > blockSize)
      break;

    bbLen = blockSize - bbLen;

    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;

    /* The first byte must be 0x6B
     */
    if (block[0] != 0x6b)
      status = VT_ERROR_INVALID_PAD;

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

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

    /* The next byte should be 0xba.
     */
    if (block[bbLen + 1] != 0xba)
      status = VT_ERROR_INVALID_PAD;

    /* The second to las byte should be the digestByte.
     */
    if (block[blockSize - 2] != (unsigned char)x931Byte)
      status = VT_ERROR_INVALID_PAD;

    /* The last byte should be 0xcc.
     */
    if (block[blockSize - 1] != 0xcc)
      status = VT_ERROR_INVALID_PAD;

    /* Move the digest to the front.
     */
    Z2Memmove (block, block + bbLen + 2, digestLen);

    *outputLen = digestLen;

  } while (0);

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

  return (status);
}

int X931RSASignData (
   VoltAlgorithmObject *obj,
   VoltKeyObject *key,
   VtRandomObject random,
   unsigned char *dataToSign,
   unsigned int dataToSignLen,
   unsigned char *signature,
   unsigned int *sigLen
   )
{
  int status, cmpResult;
  unsigned int sign, blockSize;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  VoltRsaSignCtx *rsaCtx = (VoltRsaSignCtx *)(signCtx->localSignCtx);
  VoltMpIntCtx *mpCtx = key->mpCtx;
  VoltMpInt *base = (VoltMpInt *)0;
  VoltMpInt *result = (VoltMpInt *)0;
  VoltMpInt *temp;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* For RSA, the input block size and the output block size are the
   * same.
   */
  blockSize = signCtx->paddedBlockLen;

  do
  {
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &base);
    if (status != 0)
      break;
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->OctetStringToMpInt (0, dataToSign, dataToSignLen, base);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &result);
    if (status != 0)
      break;

    /* If we have the CRT info, use it. If not, use the private
     * exponent.
     */
    if (rsaCtx->priKeyData->prime1 != (VoltMpInt *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->ModExpCRT (
        base, rsaCtx->priKeyData->prime1, rsaCtx->priKeyData->prime2,
        rsaCtx->priKeyData->expo1, rsaCtx->priKeyData->expo2,
        rsaCtx->priKeyData->coeff, result);
      if (status != 0)
        break;
    }
    else
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->ModExp (
        base, rsaCtx->priKeyData->priExpo, rsaCtx->priKeyData->modulus,
        result);
      if (status != 0)
        break;
    }

    /* Call the result s and the modulus n. The signature is defined as
     * the smaller of s and n - s. Is there a way to determine which is
     * smaller without performing the subtraction? Yes, but they're
     * likely to take as much time as simply performing the subtraction.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Subtract (rsaCtx->priKeyData->modulus, result, base);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Compare (result, base, &cmpResult);
    if (status != 0)
      break;

    /* s is in result, n - s is in base. If result > base, we want to
     * return what is in base.
     */
    if (cmpResult > 0)
    {
      temp = result;
      result = base;
      base = temp;
    }

⌨️ 快捷键说明

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