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

📄 dsasignimpl.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2003-2004, Voltage Security, all rights reserved.
 */
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "random.h"
#include "sign.h"
#include "dsa.h"
#include "mpint.h"
#include "errorctx.h"

int DSACheckSignatureInput (
   VoltAlgorithmObject *obj,
   VoltKeyObject *key,
   VtRandomObject random,
   unsigned char *dataToSign,
   unsigned int dataToSignLen,
   unsigned int *signatureSize
   )
{
  int status;
  unsigned int keyDataFlag;
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  VoltDsaSignCtx *dsaCtx = (VoltDsaSignCtx *)(signCtx->localSignCtx);
  VoltDsaPrivateKey *getKeyData;
  VtDSAPriKeyInfo *getKeyInfo;
  VtRandomObject randomToUse;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* This function not only checks the input, it sets dsaCtx values, so
   * we don't have to get them again when we're inside SignData.
   */

  do
  {
    /* How big will the signature be? It depends on the format.
     */
    *signatureSize = VOLT_RAW_DSA_SIG_LEN;
    if (dsaCtx->format == VT_DSA_SIGNATURE_DER_ENCODED)
      *signatureSize = VOLT_DER_DSA_SIG_LEN;

    /* Make sure the key is a DSA private key. Also, this implementation
     * needs the key as data.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_KEY_OBJ;
    if ((key->keyType & VOLT_KEY_TYPE_MASK_ASYM_ALG) != VOLT_KEY_ALG_DSA)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if ((key->keyType & VOLT_KEY_TYPE_PRIVATE) == 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (key->mpCtx == (VoltMpIntCtx *)0)
      break;

    /* See if the key data is already in the form we want it. If so,
     * reset keyDataFlag to 1.
     */
    keyDataFlag = 0;
    if ((key->keyType & VOLT_KEY_TYPE_MASK_DATA) == VOLT_KEY_TYPE_DATA)
    {
      getKeyData = (VoltDsaPrivateKey *)(key->keyData);
      if (getKeyData->type == VOLT_KEY_TYPE_PRIVATE)
        keyDataFlag = 1;
    }

    /* If we were not able to get the key data in the form we wanted
     * it, see if we can create it.
     */
    if (keyDataFlag == 0)
    {
      /* Can we get the key data out of the object?
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGetKeyParam (
        (VtKeyObject)key, VtKeyParamDSAPrivate, (Pointer *)&getKeyInfo);
      if (status == VT_ERROR_GET_INFO_UNAVAILABLE)
        status = VT_ERROR_INVALID_KEY_OBJ;
      if (status != 0)
        break;

      VtDestroyKeyObject (&(dsaCtx->tempKey));
      dsaCtx->priKeyData = (VoltDsaPrivateKey *)0;
      dsaCtx->pubKeyData = (VoltDsaPublicKey *)0;

      /* Create a key object we know will possess the key data the way
       * we want it.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        obj->voltObject.libraryCtx, VtKeyImplMpCtx, (Pointer)(key->mpCtx),
        &(dsaCtx->tempKey));
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtSetKeyParam (
        dsaCtx->tempKey, VtKeyParamDSAPrivate, (Pointer)getKeyInfo);
      if (status != 0)
        break;

      key = (VoltKeyObject *)(dsaCtx->tempKey);
      getKeyData = (VoltDsaPrivateKey *)(key->keyData);

      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    }

    /* The signer will need a valid random.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_RANDOM_OBJECT;
    randomToUse = random;
    if (random == (VtRandomObject)0)
    {
      randomToUse = (VtRandomObject)VoltGetLibCtxInfo (
        obj->voltObject.libraryCtx, VOLT_LIB_CTX_INFO_TYPE_RANDOM);

      if (randomToUse == (VtRandomObject)0)
        break;
    }

    VOLT_SET_FNCT_LINE (fnctLine)
    if (VOLT_OBJECT_TYPE_NOT_EQUAL (randomToUse, VOLT_OBJECT_TYPE_RANDOM))
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (((VoltRandomObject *)randomToUse)->enabled == 0)
      break;

    /* The digest algorithm must be SHA-1.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    if (signCtx->digestAlg != VT_DIGEST_ALG_SHA1)
      break;

    /* The dataToSignLen must be 20 bytes long.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (dataToSignLen != VOLT_DSA_SIGN_DATA_LEN)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_NULL_ARG;
    if (dataToSign == (unsigned char *)0)
      break;

    signCtx->paddedBlockLen = VOLT_DSA_SIGN_DATA_LEN;
    dsaCtx->random = randomToUse;
    dsaCtx->priKeyData = getKeyData;
    status = 0;

  } while (0);

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

  return (status);
}

int DSASignData (
   VoltAlgorithmObject *obj,
   VoltKeyObject *key,
   VtRandomObject random,
   unsigned char *dataToSign,
   unsigned int dataToSignLen,
   unsigned char *signature,
   unsigned int *sigLen
   )
{
  int status, testInt;
  unsigned int sign, valLen, index, leadByte;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  VoltDsaSignCtx *dsaCtx = (VoltDsaSignCtx *)(signCtx->localSignCtx);
  VoltDsaPrivateKey *keyData = (VoltDsaPrivateKey *)(key->keyData);
  VoltMpIntCtx *mpCtx = key->mpCtx;
  VtRandomObject rand = (VtRandomObject)0;
  VoltMpInt *kVal = (VoltMpInt *)0;
  VoltMpInt *kInv = (VoltMpInt *)0;
  VoltMpInt *rVal = (VoltMpInt *)0;
  VoltMpInt *sVal = (VoltMpInt *)0;
  VtFips186PrngInfo randInfo;
  unsigned char *subprimeQ = (unsigned char *)0;
  unsigned char *buf;
  VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
  unsigned char xkey[VOLT_DSA_XKEY_LEN];
  unsigned char xseed[VOLT_DSA_XSEED_LEN];
  unsigned char kValBuf[VOLT_DSA_K_VAL_LEN];
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* This function expects the random and keyData values inside the
   * dsaCtx are set with the appropriate info.
   */

  do
  {
    /* If there's a surrender ctx, call the Surrender function.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if ( ((obj->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
         (obj->voltObject.surrenderCtx != (Pointer)0) )
    {
      surrCtx = (VoltSurrenderCtx *)(obj->voltObject.surrenderCtx);
      surrCtx->surrenderInfo.callingFlag = VT_SURRENDER_FNCT_DSA_SIGN;
      surrCtx->surrenderInfo.callCount = 3;
      surrCtx->surrenderInfo.callNumber = 1;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = surrCtx->Surrender (
        surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
      if (status != 0)
        break;
    }

    /* Fill in the xkey and xseed buffers.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGenerateRandomBytes (dsaCtx->random, xkey, VOLT_DSA_XKEY_LEN);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGenerateRandomBytes (dsaCtx->random, xseed, VOLT_DSA_XSEED_LEN);
    if (status != 0)
      break;

    /* We need subprimeQ for the generation of k.
     */
    if (dsaCtx->priKeyData->keyItems == (VtDSAPriKeyInfo *)0)
    {
      /* How big does the buffer need to be?
       * We're expecting a BufferTooSmall error, if we don't get it,
       * that's an error.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->MpIntToOctetString (
        keyData->subprimeQ, &sign, (unsigned char *)0, 0, &valLen);
      if (status == 0)
        status = VT_ERROR_INVALID_KEY_OBJ;
      if (status != VT_ERROR_BUFFER_TOO_SMALL)
        break;

      /* Allocate a buffer to hold the subprime.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      subprimeQ = (unsigned char *)Z2Malloc (valLen, 0);
      if (subprimeQ == (unsigned char *)0)
        break;

      /* Now get the data.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->MpIntToOctetString (
        keyData->subprimeQ, &sign, subprimeQ, valLen, &valLen);
      if (status != 0)
        break;

      randInfo.primeQ.data = subprimeQ;
      randInfo.primeQ.len = valLen;
    }
    else
    {
      randInfo.primeQ.data = keyData->keyItems->subprimeQ.data;
      randInfo.primeQ.len = keyData->keyItems->subprimeQ.len;
    }

    /* For generating random k, use technique 3.2 of the FIPS 186
     * standard.
     */
    randInfo.variation = FIPS_186_PRNG_3_2_CERTIFY;
    randInfo.mpCtx = (VtMpIntCtx)mpCtx;
    randInfo.XKEY.data = xkey;
    randInfo.XKEY.len = VOLT_DSA_XKEY_LEN;

    /* Build a random object that will generate the random k in a FIPS
     * prescibed manner.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateRandomObject (
      (VtLibCtx)libCtx, VtRandomImplFips186Prng, (Pointer)&randInfo, &rand);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtSeedRandom (rand, xseed, VOLT_DSA_XSEED_LEN);
    if (status != 0)
      break;

    /* We're now ready to create the DSA signature.
     *   g is the base, x is the private value in the private key.
     *   k = random value < q
     *   kInv = k^(-1) mod q (the inverse of k mod q)
     *   r = (g^k mod p) mod q
     *   xr = (x * r) mod q
     *   s = (kInv * (digest + xr)) mod q
     */

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

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

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

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

    if (surrCtx != (VoltSurrenderCtx *)0)
    {
      surrCtx->surrenderInfo.callingFlag = VT_SURRENDER_FNCT_DSA_SIGN;
      surrCtx->surrenderInfo.callCount = 3;
      surrCtx->surrenderInfo.callNumber = 2;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = surrCtx->Surrender (
        surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
      if (status != 0)
        break;
    }

    /* Create a loop to do this a number of times in case we generate a
     * "bad" k. If the r or s values are 0, or if there is no inverse
     * to k, generate a new k.
     * Try this an "arbitrary" 100 times. If, after 100 tries we still
     * can't get a signature, return an error.
     * In the real world, using real parameters, the probability of
     * generating a "bad" k and getting a bad signature are so small,
     * this loop will never actually run more than once. But it's there
     * just in case.
     */
    for (index = 0; index < 100; ++index)
    {
      /* Generate the random k.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGenerateRandomBytes (rand, kValBuf, VOLT_DSA_K_VAL_LEN);
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = mpCtx->OctetStringToMpInt
        (0, kValBuf, VOLT_DSA_K_VAL_LEN, kVal);
      if (status != 0)

⌨️ 快捷键说明

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