📄 dsasignimpl.c
字号:
/* 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 + -