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

📄 fips186impl.c

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

/* Find sum += addend.
 * <p>You should not call this function is addendLen is longer than
 * sumLen.
 * <p>This will add word 0 of addend to the word 0 of sum and retain
 * the carry. It will then add word 1 of addend (if there is one) to
 * word 1 of sum and then add in the carry from the previous add. It
 * will then retain the carry from this addition. It will continue in
 * this fashion until adding all of addend's bytes to sum. If there is
 * a carry beyond the end of sum, it is lost.
 *
 * @param addend One of the addends.
 * @param sum The other addend, also where the result goes.
 * @param len The length of the buffers.
 * @return none
 */
static void VOLT_CALLING_CONV AddBuffers VOLT_PROTO_LIST ((
   unsigned char *addend,
   unsigned int addendLen,
   unsigned char *sum,
   unsigned int sumLen
));

/* Test a seed buffer to make sure it meets the FIPS seed requirments.
 * <p>If the seed passes, return 0, if not, return
 * VT_ERROR_INSUFFICIENT_SEED.
 *
 * @param libCtx The libCtx to use.
 * @param fips186Ctx The context containing the seed buffer with the
 * seed to test.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV TestSeed VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VoltFips186PrngCtx *fips186Ctx
));

/* This updates XKEY.
 * <p> It also produces a block of output.
 *
 * @param libCtx The libCtx to use.
 * @param fips186Ctx The context containing the XKEY and info
 * necessary to update the state.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV UpdateXKEY VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VoltFips186PrngCtx *fips186Ctx
));

/* Test the output, to make sure it's not the same thing as the last
 * block, as required by FIPS.
 * <p>If the "previous block" buffer is empty, this is the first call
 * to GenerateRandomBytes. We want to copy the output data into the
 * previous block buffer, but not return it to the app that called
 * VtGenerateRandomBytes.
 * <p>If the output passes, return 0, if not, return
 * VT_ERROR_RANDOM_OBJECT.
 *
 * @param libCtx The libCtx to use.
 * @param fips186Ctx The context containing the blokc of output to test.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV TestOutput VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VoltFips186PrngCtx *fips186Ctx
));

int FIPS186SeedRandom (
   VoltRandomObject *obj,
   unsigned char *seedData,
   unsigned int seedLen
   )
{
  int status;
  unsigned int count;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltFips186PrngCtx *fips186Ctx = (VoltFips186PrngCtx *)(obj->localRandomCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If there are no seed bytes, this implementation does nothing.
   */
  if ( (seedData == (unsigned char *)0) || (seedLen == 0) )
    return (0);

  do
  {
    /* Place the seed bytes into the seed buffer.
     */
    count = fips186Ctx->byteSize - fips186Ctx->seedLen;
    if (seedLen < count)
      count = seedLen;

    Z2Memcpy (fips186Ctx->seedBuffer + fips186Ctx->seedLen, seedData, count);
    seedLen -= count;
    seedData += count;
    fips186Ctx->seedLen += count;
    if (fips186Ctx->seedCount <= FIPS_186_PRNG_MIN_SEED_LEN)
      fips186Ctx->seedCount += count;

    if ( (fips186Ctx->seedCount == FIPS_186_PRNG_MIN_SEED_LEN) &&
         (fips186Ctx->seedLen == fips186Ctx->byteSize) )
    {
      /* Test the first block of seed.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = TestSeed (libCtx, fips186Ctx);
      if (status != 0)
        break;
    }

    /* If there are no more seed bytes, we're done with this routine,
     * we'll do something with the seed when we need to.
     */
    status = 0;
    if (seedLen == 0)
      break;

    /* If we have more seed input, Update the internal state with the
     * previously saved seed material.
     */
    if (fips186Ctx->seedCount <= FIPS_186_PRNG_MIN_SEED_LEN)
      fips186Ctx->seedCount = FIPS_186_PRNG_MIN_SEED_LEN + 1;
    do
    {
      /* Copy the seed material into the XSEED buffer.
       */
      Z2Memcpy (
        fips186Ctx->xseed, fips186Ctx->seedBuffer, fips186Ctx->byteSize);
      fips186Ctx->seedLen = 0;

      /* Do the XKEY update to alter the internal state.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = UpdateXKEY (libCtx, fips186Ctx);
      if (status != 0)
        break;

      /* The call to UpdateXKEY generated output, but we aren't
       * interested in that, we were simply interested in changing the
       * state. So set currentBytesLen to indicate we should ignore the
       * data therein.
       */
      fips186Ctx->currentBytesLen = 0;

      /* Copy the next bytes of seedData input into the seedBuffer.
       */
      count = fips186Ctx->byteSize;
      if (seedLen < count)
        count = seedLen;

      Z2Memcpy (fips186Ctx->seedBuffer, seedData, count);
      seedLen -= count;
      seedData += count;
      fips186Ctx->seedLen = count;
    } while (seedLen != 0);

  } while (0);

  VOLT_LOG_ERROR_COMPARE (
    status, (VtLibCtx)libCtx, status, 0, fnctLine,
    "FIPS186SeedRandom", (char *)0)

  return (status);
}

int FIPS186GenerateRandomBytes (
   VoltRandomObject *obj,
   unsigned char *randomBytes,
   unsigned int randomLen
   )
{
  int status, seedStatus;
  unsigned int count, offset;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltFips186PrngCtx *fips186Ctx = (VoltFips186PrngCtx *)(obj->localRandomCtx);
  unsigned char *source;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* If the the app has not added a min count of seed bytes yet, hold
     * on to that information.
     */
    status = 0;
    seedStatus = VT_ERROR_INSUFFICIENT_SEED;
    if (fips186Ctx->seedCount >= FIPS_186_PRNG_MIN_SEED_LEN)
      seedStatus = 0;

    /* If we have seed data in the seedBuffer and the count is >
     * MIN_SEED_LEN, then we need to update XKEY. If the count is <= to
     * MIN_SEED_LEN, then the material in the seedBuffer is the first
     * block of seed, just move it into the XSEED buffer.
     */
    if (fips186Ctx->seedLen != 0)
    {
      if (fips186Ctx->seedCount <= FIPS_186_PRNG_MIN_SEED_LEN)
      {
        Z2Memcpy (
          fips186Ctx->xseed, fips186Ctx->seedBuffer, fips186Ctx->seedLen);
        fips186Ctx->seedLen = 0;
      }
      else
      {
        /* Copy the seed material into the XSEED buffer.
         */
        offset = fips186Ctx->byteSize - fips186Ctx->seedLen;
        Z2Memset (fips186Ctx->xseed, 0, offset);
        Z2Memcpy (
          fips186Ctx->xseed + offset, fips186Ctx->seedBuffer,
          fips186Ctx->seedLen);
        fips186Ctx->seedLen = 0;

        /* Do the XKEY update to alter the internal state.
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = UpdateXKEY (libCtx, fips186Ctx);
        if (status != 0)
          break;

        /* The call to UpdateXKEY generated output, but we aren't
         * interested in that, we were simply interested in changing the
         * state. So set currentBytesLen to indicate we should ignore the
         * data therein.
         */
        fips186Ctx->currentBytesLen = 0;
      }
    }

    /* Do we have any bytes available for output?
     */
    if (fips186Ctx->currentBytesLen > 0)
    {
      /* Copy bytes to the output. If the previousBytesFlag is
       * SECOND_BLOCK, copy from the previousBytes buffer. It is the
       * first block produced, but we never compared it to another
       * block (and never output it) until we got the second block. Now
       * that we have compared it, we can return it.
       * <p>If previousBytesFlag is not SECOND_BLOCK, get output from
       * currentBytes.
       */
      source = fips186Ctx->previousBytes;
      if (fips186Ctx->previousBytesFlag != VOLT_FIPS_186_PREVIOUS_BUFFER)
        source = fips186Ctx->currentBytes;

      count = fips186Ctx->currentBytesLen;
      if (randomLen < count)
        count = randomLen;
      Z2Memcpy (randomBytes, source + fips186Ctx->currentBytesOffset, count);
      randomLen -= count;
      randomBytes += count;
      fips186Ctx->currentBytesOffset += count;
      fips186Ctx->currentBytesLen -= count;
      /* Was that enough?
       */
      status = 0;
      if (randomLen == 0)
        break;
    }

    /* Generate blocks of output until we've generated enough blocks to
     * fill the output buffer.
     */
    do
    {
      /* If previousBytesFlag is PREVIOUS_BUFFER, we already have the
       * next block of data in the currentBytes buffer, we don't need
       * to update XKEY. But if it is not, generate another block.
       */
      if (fips186Ctx->previousBytesFlag != VOLT_FIPS_186_PREVIOUS_BUFFER)
      {
        /* This will generate a block of output as well as update XKEY.
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = UpdateXKEY (libCtx, fips186Ctx);
        if (status != 0)
          break;
      }

      /* This function will test the output against the previous block,
       * unless there is no previous block, in which case this function
       * will only initialize the "previous block" buffer.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = TestOutput (libCtx, fips186Ctx);
      if (status != 0)
        break;

      /* If we have no length of output, generate another block.
       */
      if (fips186Ctx->currentBytesLen == 0)
        continue;

      count = fips186Ctx->currentBytesLen;
      if (randomLen < count)
        count = randomLen;

      /* Copy bytes to the output. The previousBytesFlag tells us which
       * buffer to copy from.
       */
      source = fips186Ctx->previousBytes;
      if (fips186Ctx->previousBytesFlag != VOLT_FIPS_186_PREVIOUS_BUFFER)
        source = fips186Ctx->currentBytes;

      Z2Memcpy (randomBytes, source, count);
      randomLen -= count;
      randomBytes += count;
      fips186Ctx->currentBytesOffset += count;
      fips186Ctx->currentBytesLen -= count;

    } while (randomLen != 0);

  } while (0);

  /* There are two int's holding error codes, status and seedStatus. If
   * both are 0, there is no error, return 0. If status is not 0, return
   * that error, even if seedStatus is not 0. If status is 0, but
   * seedStatus is not 0, return the seedStatus error.
   */
  if (status == 0)
    status = seedStatus;

  VOLT_LOG_ERROR_COMPARE (
    status, (VtLibCtx)libCtx, status, 0, fnctLine,
    "FIPS186GenerateRandomBytes", (char *)0)

⌨️ 快捷键说明

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