📄 dsasignimpl.c
字号:
break;
/* Find (g ^ k mod p) mod q. Do this before finding kInv so we can
* use kInv as a temp variable.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModExp
(keyData->baseG, kVal, keyData->primeP, kInv);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModReduce (kInv, keyData->subprimeQ, rVal);
if (status != 0)
break;
/* Find xr mod q next, use kInv as a temp variable. Place the
* result into sVal (another temp variable).
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->Multiply (keyData->priValX, rVal, kInv);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModReduce (kInv, keyData->subprimeQ, sVal);
if (status != 0)
break;
/* Find k^(-1) (k inverse).
* If subprimeQ is truly prime, there will be an inverse to k.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModInvert (kVal, keyData->subprimeQ, kInv);
if (status != 0)
{
/* If the error is something other than NoInverse, we're done.
*/
if (status != VT_ERROR_NO_INVERSE)
break;
/* No inverse, try a new k. If we've tried too many times,
* we'll quit with SignatureComputation error.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_SIGNATURE_COMPUTATION;
continue;
}
/* Compute digest + xr. We're done with k, so use kVal as a temp
* variable. Recall that xr is currently in sVal.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->OctetStringToMpInt (0, dataToSign, dataToSignLen, kVal);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->Add (kVal, sVal, sVal);
if (status != 0)
break;
/* Multiply (digest + xr) by kInv mod q. Use kVal as a temp
* variable. This is s.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->Multiply (sVal, kInv, kVal);
if (status != 0)
break;
/* Place the result into sVal.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModReduce (kVal, keyData->subprimeQ, sVal);
if (status != 0)
break;
/* Check to see if r or s is 0. If so, try a new k.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->MpIntToInt (rVal, 1, &testInt);
if (status == 0)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_SIGNATURE_COMPUTATION;
if (testInt == 0)
continue;
}
status = mpCtx->MpIntToInt (sVal, 1, &testInt);
if (status == 0)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_SIGNATURE_COMPUTATION;
if (testInt == 0)
continue;
}
/* If we reach this code, the computations worked, we were
* successful.
*/
status = 0;
break;
}
if (status != 0)
break;
/* Place r and s into the signature buffer. If RAW, just place them
* into the buffer side by side (leading 00 bytes if a value is not
* entirely 20 bytes long).
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
if (dsaCtx->format == VT_DSA_SIGNATURE_R_S)
{
/* Get r.
*/
VOLT_SET_FNCT_LINE (fnctLine)
buf = signature;
status = mpCtx->MpIntToOctetString
(rVal, &sign, buf, VOLT_DSA_R_VAL_LEN, &valLen);
if (status != 0)
break;
/* If less than 20 bytes, redo the get to lead with 00 bytes.
* This will almost never happen, so the inefficiency is not
* likely to be an issue.
*/
if (valLen != VOLT_DSA_R_VAL_LEN)
{
VOLT_SET_FNCT_LINE (fnctLine)
Z2Memset (buf, 0, VOLT_DSA_R_VAL_LEN);
status = mpCtx->MpIntToOctetString
(rVal, &sign, buf + VOLT_DSA_R_VAL_LEN - valLen, valLen, &valLen);
if (status != 0)
break;
}
/* Get s.
*/
VOLT_SET_FNCT_LINE (fnctLine)
buf = signature + VOLT_DSA_R_VAL_LEN;
status = mpCtx->MpIntToOctetString
(sVal, &sign, buf, VOLT_DSA_S_VAL_LEN, &valLen);
if (status != 0)
break;
/* If less than 20 bytes, redo the get to lead with 00 bytes.
* This will almost never happen, so the inefficiency is not
* likely to be an issue.
*/
if (valLen != VOLT_DSA_S_VAL_LEN)
{
VOLT_SET_FNCT_LINE (fnctLine)
Z2Memset (buf, 0, VOLT_DSA_S_VAL_LEN);
status = mpCtx->MpIntToOctetString
(sVal, &sign, buf + VOLT_DSA_S_VAL_LEN - valLen, valLen, &valLen);
if (status != 0)
break;
}
*sigLen = VOLT_DSA_R_VAL_LEN + VOLT_DSA_S_VAL_LEN;
/* If R_S format, this is the last call to surrender.
*/
if (surrCtx != (VoltSurrenderCtx *)0)
{
surrCtx->surrenderInfo.callingFlag = VT_SURRENDER_FNCT_DSA_SIGN;
surrCtx->surrenderInfo.callCount = 3;
surrCtx->surrenderInfo.callNumber = 3;
VOLT_SET_FNCT_LINE (fnctLine)
status = surrCtx->Surrender (
surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
if (status != 0)
break;
}
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.
*/
if (surrCtx != (VoltSurrenderCtx *)0)
{
surrCtx = (VoltSurrenderCtx *)(obj->voltObject.surrenderCtx);
surrCtx->surrenderInfo.callingFlag = VT_SURRENDER_FNCT_DSA_SIGN;
surrCtx->surrenderInfo.callCount = 3;
surrCtx->surrenderInfo.callNumber = 3;
VOLT_SET_FNCT_LINE (fnctLine)
status = surrCtx->Surrender (
surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
if (status != 0)
break;
}
} 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.
*/
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_VERIFY;
surrCtx->surrenderInfo.callCount = 3;
surrCtx->surrenderInfo.callNumber = 1;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = surrCtx->Surrender (
surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
if (status != 0)
break;
}
/* 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -