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

📄 dsasignimpl.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 2 页
字号:
      /* If R_S format, this is the last call to surrender.
       */
      VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_DSA_SIGN, 3, 3)

      status = 0;
      break;
    }

    /* DER encode the r and s.
     *
     *    SEQUENCE {
     *      r   INTEGER
     *      s   INTEGER }
     *
     * First, how big is r? Is the lead bit 1? If so, prepend a 00 byte.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    buf = signature + 4;
    leadByte = 1;
    status = mpCtx->MpIntToOctetString
      (rVal, &sign, buf, VOLT_DSA_R_VAL_LEN, &valLen);
    if (status != 0)
      break;
    if ((buf[0] & 0x80) == 0)
      leadByte = 0;

    /* If we need a leading 00 byte, move r one byte over.
     */
    if (leadByte == 1)
    {
      for (index = valLen; index > 0; --index)
        buf[index] = buf[index - 1];
      buf[0] = 0;
    }

    signature[0] = 0x30;
    /* The length is currently the length of r + the length of the
     * leadByte + the "02 len" of the INTEGER.
     */
    signature[1] = (unsigned char)(2 + leadByte + valLen);
    /* Place the "02 len" of the r INTEGER.
     */
    signature[2] = 0x02;
    signature[3] = (unsigned char)(leadByte + valLen);

    /* Move buf ahead to where s will be.
     */
    buf += leadByte + valLen + 2;

    /* Get s.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    leadByte = 1;
    status = mpCtx->MpIntToOctetString
      (sVal, &sign, buf, VOLT_DSA_S_VAL_LEN, &valLen);
    if (status != 0)
      break;
    if ((buf[0] & 0x80) == 0)
      leadByte = 0;

    /* If we need a leading 00 byte, move r one byte over.
     */
    if (leadByte == 1)
    {
      for (index = valLen; index > 0; --index)
        buf[index] = buf[index - 1];
      buf[0] = 0;
    }

    /* Add to the length the length of s + the length of the leadByte +
     * the "02 len" of the INTEGER.
     */
    signature[1] += (unsigned char)(2 + leadByte + valLen);
    /* Place the "02 len" of the s INTEGER.
     */
    buf -= 2;
    buf[0] = 0x02;
    buf[1] = (unsigned char)(leadByte + valLen);

    *sigLen = (unsigned int)(signature[1]) + 2;

    /* If DER format, this is the last call to surrender.
     */
    VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_DSA_SIGN, 3, 3)

  } while (0);

  Z2Memset (kValBuf, 0, VOLT_DSA_PRI_VAL_LEN);
  Z2Memset (xkey, 0, VOLT_DSA_XKEY_LEN);
  Z2Memset (xseed, 0, VOLT_DSA_XSEED_LEN);
  VtDestroyRandomObject (&rand);

  if (kVal != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&kVal);
  if (kInv != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&kInv);
  if (rVal != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&rVal);
  if (sVal != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&sVal);

  if (subprimeQ != (unsigned char *)0)
    Z2Free (subprimeQ);

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

  return (status);
}

int DSAVerifyData (
   VoltAlgorithmObject *obj,
   VoltKeyObject *key,
   VtRandomObject random,
   unsigned char *dataToVerify,
   unsigned int dataToVerifyLen,
   unsigned char *signature,
   unsigned int sigLen,
   unsigned int *verifyResult
   )
{
  int status;
  unsigned int keyDataFlag, rLen, sLen, compareResult;
  VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
  VoltDsaSignCtx *dsaCtx = (VoltDsaSignCtx *)(signCtx->localSignCtx);
  VoltDsaPublicKey *getKeyData;
  VtDSAPubKeyInfo *getKeyInfo;
  VoltMpIntCtx *mpCtx = key->mpCtx;
  VoltMpInt *rVal = (VoltMpInt *)0;
  VoltMpInt *sVal = (VoltMpInt *)0;
  VoltMpInt *sInv = (VoltMpInt *)0;
  VoltMpInt *u1Val = (VoltMpInt *)0;
  VoltMpInt *u2Val = (VoltMpInt *)0;
  unsigned char *rValBuf;
  unsigned char *sValBuf;
  VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* Initialize to not verified. If all the checks pass, we'll change
   * it at the end.
   */
  *verifyResult = 0;

  do
  {
    /* If there's a surrender ctx, call the Surrender function.
     */
    VOLT_GET_OBJECT_SURR_CTX (surrCtx, obj);
    VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_DSA_VERIFY, 3, 1)

    /* Make sure the key is a DSA public 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_PUBLIC) == 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 = (VoltDsaPublicKey *)(key->keyData);
      if ( (getKeyData->type == VOLT_KEY_TYPE_PUBLIC) ||
           (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, VtKeyParamDSAPublic, (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 = (VoltDsaPublicKey *)(key->keyData);

      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    }

    /* 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 input must be 20 bytes.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (dataToVerifyLen != VOLT_DSA_SIGN_DATA_LEN)
      break;

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

    /* What is the format of the signature?
     */
    if (dsaCtx->format == VT_DSA_SIGNATURE_R_S)
    {
      /* The signature should be exacly 40 bytes long.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT_LENGTH;
      if (sigLen != (VOLT_DSA_R_VAL_LEN + VOLT_DSA_S_VAL_LEN))
        break;

      rValBuf = signature;
      rLen = VOLT_DSA_R_VAL_LEN;
      sValBuf = signature + VOLT_DSA_R_VAL_LEN;
      sLen = VOLT_DSA_S_VAL_LEN;
    }
    else
    {
      /* Decode the signature.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT;
      if (sigLen < 2)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (signature[0] != 0x30)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (signature[1] != (unsigned char)(sigLen - 2))
        break;

      sigLen -= 2;
      signature += 2;

      /* We're expecting an INTEGER here.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (sigLen < 2)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (signature[0] != 0x02)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (signature[1] > (unsigned char)(VOLT_DSA_R_VAL_LEN + 1))
        break;

      rLen = (unsigned int)(signature[1]);
      sigLen -= 2;
      signature += 2;

      /* Locate r.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (sigLen < rLen)
        break;
      rValBuf = signature;

      sigLen -= rLen;
      signature += rLen;

      /* We're expecting an INTEGER here.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (sigLen < 2)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (signature[0] != 0x02)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (signature[1] > (unsigned char)(VOLT_DSA_S_VAL_LEN + 1))
        break;

      sLen = (unsigned int)(signature[1]);
      sigLen -= 2;
      signature += 2;

      /* Locate s.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (sigLen < sLen)
        break;
      sValBuf = signature;

      VOLT_SET_FNCT_LINE (fnctLine)
      sigLen -= sLen;
      if (sigLen != 0)
        break;
    }

    /* Do the verification math.
     *   g is the base, y is the public value in the public key.
     *   r is the r value and s the s value in the signature.
     *   sInv = s ^ (-1) mod q
     *   u1 = (digest * sInv) mod q
     *   u2 = (r * sInv) mod q
     *   a = (g ^ u1) mod p
     *   b = (y ^ u2) mod p
     *   v = ((a * b) mod p) mod q
     * If v == r, the signature verifies.
     */

    /* Get r and s as MpInt's.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &rVal);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->OctetStringToMpInt (0, rValBuf, rLen, rVal);
    if (status != 0)
      break;

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

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->OctetStringToMpInt (0, sValBuf, sLen, sVal);
    if (status != 0)
      break;

    VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_DSA_VERIFY, 3, 2)

    /* Compute sInv.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &sInv);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModInvert (sVal, getKeyData->subprimeQ, sInv);
    /* If the error is no inverse, the signature does not verify.
     */
    if (status == VT_ERROR_NO_INVERSE)
    {
      /* verifyResult is set to 0 (no/false). There's no error, the sig
       * just doesn't verify.
       */
      status = 0;
      break;
    }

    /* If there is an error and it is something other than NoInverse,
     * pass it on.
     */
    if (status != 0)
      break;

    /* Compute u1, use u2Val and sVal as temp veraiables.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &u1Val);
    if (status != 0)
      break;

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

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->OctetStringToMpInt
      (0, dataToVerify, dataToVerifyLen, u2Val);
    if (status != 0)
      break;

    /* u1 = (digest * sInv) mod q
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Multiply (u2Val, sInv, sVal);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModReduce (sVal, getKeyData->subprimeQ, u1Val);
    if (status != 0)
      break;

    /* Compute u2, use sVal as a temp variable.
     * u2 = (r * sInv) mod q
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Multiply (rVal, sInv, sVal);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModReduce (sVal, getKeyData->subprimeQ, u2Val);
    if (status != 0)
      break;

    /* Compute a and b. Place them into sVal and sInv.
     * a = (g ^ u1) mod p
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModExp (
      getKeyData->baseG, u1Val, getKeyData->primeP, sVal);
    if (status != 0)
      break;

    /* b = (y ^ u2) mod p
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModExp (
      getKeyData->pubValY, u2Val, getKeyData->primeP, sInv);
    if (status != 0)
      break;

    /* Find v = ((a * b) mod p) mod q
     * Use u1Val and u2Val as temp variables.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Multiply (sVal, sInv, u1Val);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModReduce (u1Val, getKeyData->primeP, u2Val);
    if (status != 0)
      break;

    /* The final mod reduction produces v, place it into sVal.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModReduce (u2Val, getKeyData->subprimeQ, sVal);
    if (status != 0)
      break;

    /* Compare v and r (v is in sVal).
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Compare (rVal, sVal, &compareResult);
    if (status != 0)
      break;

    if (compareResult == 0)
      *verifyResult = 1;

    VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_DSA_VERIFY, 3, 3)

  } while (0);

  if (rVal != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&rVal);
  if (sVal != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&sVal);
  if (sInv != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&sInv);
  if (u1Val != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&u1Val);
  if (u2Val != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&u2Val);

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

  return (status);
}

⌨️ 快捷键说明

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