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

📄 opensslbnwrap.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "mpint.h"
#include "opensslbnwrap.h"
#include "errorctx.h"
#include "openssl/bn.h"
#include "openssl/err.h"

int OpenSSLBnWrapCreateMpInt (
   Pointer mpIntCtx,
   VoltMpInt **newInt
   )
{
  int status;
  unsigned int bufferSize;
  unsigned char *buffer = (unsigned char *)0;
  VoltMpIntCtx *mpCtx = (VoltMpIntCtx *)mpIntCtx;
  VoltLibCtx *libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);
  VoltMpInt *mpInt;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Allocate space for the VoltMpInt.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    bufferSize = sizeof (VoltMpInt);
    buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;
    Z2Memset (buffer, 0, bufferSize);

    /* Position the pointers.
     */
    mpInt = (VoltMpInt *)buffer;
    mpInt->mpCtx = (VtMpIntCtx)mpCtx;

    /* The mpInt field of the VoltMpInt will be a BIGNUM *.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    mpInt->mpInt = (Pointer)BN_new ();
    if (mpInt->mpInt == (Pointer)0)
      break;

    /* Initialize to zero.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if (BN_set_word ((BIGNUM *)(mpInt->mpInt), 0) == 0)
      break;

    *newInt = (VoltMpInt *)mpInt;

    status = 0;

  } while (0);

  /* If successful, just return.
   */
  if (status == 0)
    return (0);

  /* If error, free memory.
   */
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

  VOLT_LOG_ERROR (
    libCtx, status, VT_ERROR_TYPE_PRIMARY, fnctLine,
    "OpenSSLBnWrapCreateMpInt", (char *)0)

  return (status);
}

int OpenSSLBnWrapDestroyMpInt (
   VoltMpInt **theInt
   )
{
  VoltMpIntCtx *mpCtx;
  VoltLibCtx *libCtx;

  /* Call the clear function for the mpz, then free up the MpInt's
   * memory.
   */
  if (theInt == (VoltMpInt **)0)
    return (0);
  if (*theInt == (VoltMpInt *)0)
    return (0);

  /* Destroy the BIGNUM in the mpInt.
   */
  if ((*theInt)->mpInt != (Pointer)0)
    BN_clear_free ((BIGNUM *)((*theInt)->mpInt));

  mpCtx = (VoltMpIntCtx *)((*theInt)->mpCtx);
  libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);

  Z2Free (*theInt);

  *theInt = (VoltMpInt *)0;

  return (0);
}

int OpenSSLBnWrapOctetStringToMpInt (
   unsigned int sign,
   unsigned char *sourceOctetString,
   unsigned int sourceOctetStringLen,
   VoltMpInt *destInt
   )
{
  int status;
  BIGNUM *bnTarget, *dummyBn;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If NULL, we can't log an error, no libCtx.
   */
  if (destInt == (VoltMpInt *)0)
    return (VT_ERROR_NULL_ARG);

  do
  {
    /* Check the arguments.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NULL_ARG;
    if (sourceOctetString == (unsigned char *)0)
      break;
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (sourceOctetStringLen == 0)
      break;

    bnTarget = (BIGNUM *)(destInt->mpInt);

    /* Call the bn version.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    dummyBn = BN_bin2bn (
      sourceOctetString, (int)sourceOctetStringLen, bnTarget);

    /* If it worked, the result is the same as the input.
     * If they are different, there was some error, likely memory.
     */
    if (dummyBn != bnTarget)
      break;

    /* To set the sign, we can't treat the bn as an opaque type. So
     * long as the definition of BIGNUM does not change, this will work.
     * If sign is 0, the number is positive. Otherwise, the number is
     * negative. Inside a BIGNUM, if neg is 0, the number is positive,
     * if neg is 1, the number is negative.
     */
    bnTarget->neg = 1;
    if (sign == 0)
      bnTarget->neg = 0;

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_COMPARE (
    status, destInt->mpCtx->voltObject.libraryCtx, status,
    VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapOctetStringToMpInt",
    (char *)0)

  return (status);
}

int OpenSSLBnWrapIntToMpInt (
   int signCheck,
   int sourceValue,
   VoltMpInt *destInt
   )
{
  int status, posVal;
  BIGNUM *bnTarget;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If NULL, we can't log an error, no libCtx.
   */
  if (destInt == (VoltMpInt *)0)
    return (VT_ERROR_NULL_ARG);

  bnTarget = (BIGNUM *)(destInt->mpInt);

  do
  {
    status = VT_ERROR_MEMORY;

    /* If signCheck is 0, the sourceValue is an unsigned int.
     */
    if (signCheck == 0)
    {
      /* This function returns 0 for failure and presumably 1 for success.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (BN_set_word (bnTarget, (BN_ULONG)sourceValue) != 0)
        status = 0;
    }
    else
    {
      /* If signCheck is not 0, the sourceValue is a signed int.
       */
      posVal = -sourceValue;
      if (sourceValue >= 0)
        posVal = sourceValue;

      /* This function returns 0 for failure.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (BN_set_word (bnTarget, (BN_ULONG)posVal) == 0)
        break;

      /* To set the sign, we can't treat the bn as an opaque type. So
       * long as the definition of BIGNUM does not change, this will work.
       * If sign is 0, the number is positive. Otherwise, the number is
       * negative. Inside a BIGNUM, if neg is 0, the number is positive,
       * if neg is 1, the number is negative.
       */
      bnTarget->neg = 1;
      if (sourceValue >= 0)
        bnTarget->neg = 0;

      status = 0;
    }

  } while (0);

  VOLT_LOG_ERROR_COMPARE (
    status, destInt->mpCtx->voltObject.libraryCtx, status,
    VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapIntToMpInt", (char *)0)

  return (status);
}

int OpenSSLBnWrapMpIntToInt (
   VoltMpInt *sourceInt,
   int signCheck,
   int *destValue
   )
{
  int status, returnValSigned;
  unsigned int returnValUnsigned;
  BN_ULONG result;
  BIGNUM *srcBn;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If NULL, we can't log an error, no libCtx.
   */
  if (sourceInt == (VoltMpInt *)0)
    return (VT_ERROR_NULL_ARG);

  srcBn = (BIGNUM *)(sourceInt->mpInt);

  do
  {
    /* Check the arguments.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NULL_ARG;
    if (destValue == (int *)0)
      break;

    *destValue = 0;
    result = BN_get_word (srcBn);

    /* If the return is BN_MASK2, the value was too big to fit into the
     * BN_ULONG. If not, we have an answer.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MP_INT_RANGE;
    if (result == BN_MASK2)
      break;

    /* We have the answer as a BN_ULONG, get it as an unsigned int.
     */
    returnValUnsigned = (unsigned int)result;

    /* Make sure the conversion from BN_ULONG to unsigned int did not
     * lose any precision.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if (result != (BN_ULONG)returnValUnsigned)
      break;

    /* If signCheck is 0, the caller wanted the value as an unsigned
     * int.
     */
    if (signCheck == 0)
    {
      *destValue = (int)returnValUnsigned;
      status = 0;
      break;
    }

    /* The caller wants a signed int.
     * First, check to see if the value fits into a signed int. If
     * the value is negative, it was too big.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    returnValSigned = (int)returnValUnsigned;
    if (returnValSigned < 0)
      break;

    /* To get the sign, we can't treat the bn as an opaque type. So
     * long as the definition of BIGNUM does not change, this will
     * work. Inside a BIGNUM, if neg is 0, the number is positive,
     * if neg is 1, the number is negative.
     */
    *destValue = returnValSigned;
    if (srcBn->neg != 0)
      *destValue = -returnValSigned;

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_COMPARE (
    status, sourceInt->mpCtx->voltObject.libraryCtx, status,
    VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapMpIntToInt", (char *)0)

  return (status);
}

int OpenSSLBnWrapMpIntToMpInt (
   VoltMpInt *sourceInt,
   VoltMpInt *destInt
   )
{
  BIGNUM *retVal;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If NULL, we can't log an error, no libCtx.
   * We could check for one NULL, the other not, but this is the kind
   * of error an app expects not to log.
   */
  if ( (sourceInt == (VoltMpInt *)0) || (destInt == (VoltMpInt *)0) )
    return (VT_ERROR_NULL_ARG);

  /* If successful, this function returns the destination BIGNUM.
   * If the return is NULL, error. Probably the only error possible is
   * memory.
   */
  VOLT_SET_FNCT_LINE (fnctLine)
  retVal = BN_copy ((BIGNUM *)(destInt->mpInt), (BIGNUM *)(sourceInt->mpInt));
  if (retVal != (BIGNUM *)0)
    return (0);

  VOLT_LOG_ERROR (
    sourceInt->mpCtx->voltObject.libraryCtx, VT_ERROR_MEMORY,
    VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapMpIntToMpInt", (char *)0)

  return (VT_ERROR_MEMORY);
}

int OpenSSLBnWrapMpIntToOctetString (
   VoltMpInt *sourceInt,
   unsigned int *sign,
   unsigned char *destBuf,
   unsigned int bufferSize,
   unsigned int *destLen
   )
{
  int status;
  unsigned int bitLen, octLen;
  BIGNUM *sourceBn;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If NULL, we can't log an error, no libCtx.
   */
  if (sourceInt == (VoltMpInt *)0)
    return (VT_ERROR_NULL_ARG);

  sourceBn = (BIGNUM *)(sourceInt->mpInt);

  do
  {
    /* Check the arguments.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NULL_ARG;
    if ( (sign == (unsigned int *)0) || (destLen == (unsigned int *)0) )
      break;

    if (destBuf == (unsigned char *)0)
      bufferSize = 0;

    /* To get the sign, we can't treat the bn as an opaque type. So long
     * as the definition of BIGNUM does not change, this will work.
     * Inside a BIGNUM, if neg is 0, the number is positive, if neg is 1,
     * the number is negative.
     */
    *sign = 1;
    if (sourceBn->neg == 0)
      *sign = 0;

    /* How big does the buffer need to be?
     */
    bitLen = (unsigned int)BN_num_bits (sourceBn);
    octLen = 1;
    if (bitLen != 0)
      octLen = (bitLen + 7) / 8;

    /* Is the buffer big enough?
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_BUFFER_TOO_SMALL;
    *destLen = octLen;
    if (bufferSize < octLen)
      break;

    /* If bitLen is 0, the value of the BIGNUM is 0. If bitLen is not
     * 0, call the BN function to get the octet string.
     */
    destBuf[0] = 0;
    if (bitLen != 0)
      octLen = BN_bn2bin (sourceBn, destBuf);

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_COMPARE (
    status, sourceInt->mpCtx->voltObject.libraryCtx, status,
    VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapMpIntToOctetString",
    (char *)0)

  return (status);
}

int OpenSSLBnWrapCompare (
   VoltMpInt *leftInt,
   VoltMpInt *rightInt,
   int *result
   )
{
  int bnResult;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

⌨️ 快捷键说明

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