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

📄 fips186type.c

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

/* This routine does the work. It allocates and fills in the contexts.
 *
 * @param obj The random object to set.
 * @param info The info the caller passed in containing the parameters
 * of usage.
 * @param mpCtx The mpCtx to use. It may be the one in the info, it may
 * be one from the libCtx.
 * @param byteSize The size, in bytes, of the block.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV SetObjectFIPS186 VOLT_PROTO_LIST ((
   VoltRandomObject *obj,
   VtFips186PrngInfo *info,
   VtMpIntCtx mpCtx,
   unsigned int byteSize
));

/* This routine builds the digest algorithm object.
 * <p>Note, after calling this routine there will be a created and set
 * object, but it won't be initialized (DigestInit).
 *
 * @param libCtx The libCtx, it's needed to build a new object.
 * @param fips186Ctx The context to find info necessary to build and
 * where the created object will go.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV BuildDigestObject VOLT_PROTO_LIST ((
   VtLibCtx libraryCtx,
   VoltFips186PrngCtx *fips186Ctx
));

int VtRandomImplFips186Prng (
   VtRandomObject *randObj,
   Pointer info,
   unsigned int flag
   )
{
  int status;
  VoltRandomObject *obj = (VoltRandomObject *)(*randObj);
  VtFips186PrngInfo *prngInfo = (VtFips186PrngInfo *)info;
  VtMpIntCtx mpCtx = (VtMpIntCtx)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

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

    /* This InfoType has associated info.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ASSOCIATED_INFO;
    if (info == (Pointer)0)
      break;

    /* There must be XKEY and it must be within the acceptable size
     * range.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ( (prngInfo->XKEY.data == (unsigned char *)0) ||
         (prngInfo->XKEY.len < FIPS_186_PRNG_MIN_XKEY_SIZE) ||
         (prngInfo->XKEY.len > FIPS_186_PRNG_MAX_XKEY_SIZE) )
      break;

    /* The prime, if passed in, must be exactly 160 bits long. And
     * there must be an mpCtx.
     */
    if ( (prngInfo->primeQ.data != (unsigned char *)0) &&
         (prngInfo->primeQ.len != 0) )
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      if (prngInfo->primeQ.len != 20)
        break;
      VOLT_SET_FNCT_LINE (fnctLine)
      if ((prngInfo->primeQ.data[0] & 0x80) == 0)
        break;
      VOLT_SET_FNCT_LINE (fnctLine)

      status = VT_ERROR_NO_MATH_LIBRARY;
      mpCtx = prngInfo->mpCtx;
      if (mpCtx == (VtMpIntCtx)0)
      {
        mpCtx = (VtMpIntCtx)VoltGetLibCtxInfo (
          obj->voltObject.libraryCtx, VOLT_LIB_CTX_INFO_TYPE_MP_CTX);

        if (mpCtx == (VtMpIntCtx)0)
          break;
      }    

      /* We must have a valid MpIntCtx.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_INVALID_MP_INT_CTX;
      if (VOLT_OBJECT_TYPE_NOT_EQUAL (mpCtx, VOLT_OBJECT_TYPE_MP_INT_CTX))
        break;
    }

    /* Make sure the variation is valid.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ( (prngInfo->variation != FIPS_186_PRNG_3_1_ALG) &&
         (prngInfo->variation != FIPS_186_PRNG_3_1_CERTIFY) &&
         (prngInfo->variation != FIPS_186_PRNG_3_2_ALG) &&
         (prngInfo->variation != FIPS_186_PRNG_3_2_CERTIFY) )
      break;

    /* Check the object, it should not yet be set.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_SET;
    if (obj->GenerateRandomBytes != (VGenerateRandomBytes)0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = SetObjectFIPS186 (obj, prngInfo, mpCtx, 32);

  } while (0);

  /* If successful, set the FIPS bit in the object type, this object
   * is a FIPS object.
   */
  if (status == 0)
    obj->voltObject.objectType |= VOLT_OBJECT_TYPE_FIPS;

  VOLT_LOG_ERROR_COMPARE (
    status, obj->voltObject.libraryCtx, status, errorType, fnctLine,
    "VtRandomImplFips186Prng", (char *)0)

  return (status);
}

static int SetObjectFIPS186 (
   VoltRandomObject *obj,
   VtFips186PrngInfo *info,
   VtMpIntCtx mpCtx,
   unsigned int byteSize
   )
{
  int status;
  unsigned int bufferSize, offset;
  unsigned char *buffer = (unsigned char *)0;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltFips186PrngCtx *fips186Ctx;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Allocate enough space for a Fips186Ctx and buffers for xseed,
     * xkey and partial seed collection. The buffers after the struct
     * are byte arrays so we don't need to worry about alignment.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    bufferSize = sizeof (VoltFips186PrngCtx) + (3 * byteSize);
    buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;
    Z2Memset (buffer, 0, bufferSize);

    /* Locate the buffers.
     */
    fips186Ctx = (VoltFips186PrngCtx *)buffer;
    offset = sizeof (VoltFips186PrngCtx);

    /* Populate the context.
     */

    /* Clone the MpIntCtx if there is one.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (mpCtx != (VoltMpIntCtx *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCloneObject ((Pointer)mpCtx, (Pointer *)&(fips186Ctx->mpCtx));
      if (status != 0)
        break;
    }

    fips186Ctx->variation = info->variation;
    fips186Ctx->blockSizeBits = byteSize * 8;
    fips186Ctx->byteSize = byteSize;
    fips186Ctx->previousBytesFlag = VOLT_FIPS_186_INIT;
    fips186Ctx->xseed = buffer + offset;
    offset += byteSize;
    fips186Ctx->xkey = buffer + offset;
    offset += byteSize;
    fips186Ctx->seedBuffer = buffer + offset;
    /* Copy XKEY with prepended 0's (if the length is not as long as
     * the byteSize).
     */
    offset = byteSize - info->XKEY.len;
    Z2Memcpy (fips186Ctx->xkey + offset, info->XKEY.data, info->XKEY.len);

    /* We'll need a digest object.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = BuildDigestObject ((VtLibCtx)libCtx, fips186Ctx);
    if (status != 0)
      break;

    /* If there's a primeQ, get it into the context as an MpInt.
     */
    if ( (info->primeQ.data != (unsigned char *)0) &&
         (info->primeQ.len != 0) )
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = fips186Ctx->mpCtx->CreateMpInt (
        (Pointer)(fips186Ctx->mpCtx), &(fips186Ctx->primeQ));
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = fips186Ctx->mpCtx->OctetStringToMpInt (
        0, info->primeQ.data, info->primeQ.len, fips186Ctx->primeQ);
      if (status != 0)
        break;

      /* We'll need base and reduction MpInt's as well.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = fips186Ctx->mpCtx->CreateMpInt (
        (Pointer)(fips186Ctx->mpCtx), &(fips186Ctx->base));
      if (status != 0)
        break;

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

    obj->SeedRandom = FIPS186SeedRandom;
    obj->GenerateRandomBytes = FIPS186GenerateRandomBytes;
    obj->localRandomCtx = (Pointer)fips186Ctx;
    obj->LocalRandomCtxDestroy = FIPS186CtxDestroy;

    status = 0;

  } while (0);

  /* If everything worked, return 0.
   */
  if (status == 0)
    return (0);

  /* If something went wrong, destroy anything we created.
   */
  FIPS186CtxDestroy ((Pointer)obj, (Pointer)buffer);

  VOLT_LOG_ERROR (
    obj->voltObject.libraryCtx, status, errorType, fnctLine,
    "SetObjectFIPS186", (char *)0)

  return (status);
}

void FIPS186CtxDestroy (
   Pointer object,
   Pointer ctx
   )
{
  VoltRandomObject *obj = (VoltRandomObject *)object;
  VoltLibCtx *libCtx;
  VoltFips186PrngCtx *fips186Ctx = (VoltFips186PrngCtx *)ctx;

  /* Anything to destroy?
   */
  if (ctx == (Pointer)0)
    return;

  libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);

  /* First, destroy the digest object.
   */
  if (fips186Ctx->digestObj != (VtAlgorithmObject)0)
    VtDestroyAlgorithmObject (&(fips186Ctx->digestObj));

  /* If there are primeQ, base, reduction, destroy them.
   */
  if (fips186Ctx->primeQ != (VoltMpInt *)0)
    fips186Ctx->mpCtx->DestroyMpInt (&(fips186Ctx->primeQ));
  if (fips186Ctx->base != (VoltMpInt *)0)
    fips186Ctx->mpCtx->DestroyMpInt (&(fips186Ctx->base));
  if (fips186Ctx->reduction != (VoltMpInt *)0)
    fips186Ctx->mpCtx->DestroyMpInt (&(fips186Ctx->reduction));

  if (fips186Ctx->mpCtx != (VoltMpIntCtx *)0)
    VtDestroyMpIntCtx ((VtMpIntCtx *)&(fips186Ctx->mpCtx));

  /* Now, free the memory.
   */
  Z2Free (ctx);
}

static int BuildDigestObject (
   VtLibCtx libraryCtx,
   VoltFips186PrngCtx *fips186Ctx
   )
{
  int status;
  unsigned char sha1State[24] =
  {
    0x67, 0x45, 0x23, 0x01,
    0xEF, 0xCD, 0xAB, 0x89,
    0x98, 0xBA, 0xDC, 0xFE,
    0x10, 0x32, 0x54, 0x76,
    0xC3, 0xD2, 0xE1, 0xF0,
    0x67, 0x45, 0x23, 0x01,
  };
  VtGeneralSHA1Info shaInfo;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  shaInfo.padding = VT_SHA1_FIPS_186_PAD;

  /* What's the starting point? Regular SHA-1 or a shifted SHA-1 state?
   */
  shaInfo.initState.data = sha1State;
  shaInfo.initState.len = 20;
  if ( (fips186Ctx->variation == FIPS_186_PRNG_3_2_ALG) ||
       (fips186Ctx->variation == FIPS_186_PRNG_3_2_CERTIFY) )
    shaInfo.initState.data = sha1State + 4;

  /* Create the SHA-1 object with the appropriate starting point.
   */
  VOLT_SET_FNCT_LINE (fnctLine)
  status = VtCreateAlgorithmObject (
    libraryCtx, VtAlgorithmImplGeneralSHA1, (Pointer)&shaInfo,
    &(fips186Ctx->digestObj));

  VOLT_LOG_ERROR_COMPARE (
    status, libraryCtx, status, 0, fnctLine, "BuildDigestObject", (char *)0)

  return (status);
}

⌨️ 快捷键说明

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