📄 rsasignimpl.c
字号:
/* Copyright 2005-2006, Voltage Security, all rights reserved.
*/
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "sign.h"
#include "rsa.h"
#include "rsax931.h"
#include "mpint.h"
#include "errorctx.h"
int RSACheckSignatureInput (
VoltAlgorithmObject *obj,
VoltKeyObject *key,
VtRandomObject random,
unsigned char *dataToSign,
unsigned int dataToSignLen,
unsigned int *signatureSize
)
{
int status;
unsigned int modLen, digestLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
VoltRsaSignCtx *rsaCtx = (VoltRsaSignCtx *)(signCtx->localSignCtx);
VoltRsaPrivateKey *getKeyData;
VtRSAPriKeyInfo *getKeyInfo;
VoltMpIntCtx *mpCtx;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Make sure the key is an RSA 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_RSA)
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;
mpCtx = key->mpCtx;
/* We need the key data in a specified format.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetKeyParam (
(VtKeyObject)key, VtKeyParamRSAPrivateSign, (Pointer *)&getKeyInfo);
if (status == VT_ERROR_GET_INFO_UNAVAILABLE)
status = VT_ERROR_INVALID_KEY_OBJ;
if (status != 0)
break;
VtDestroyKeyObject (&(rsaCtx->tempKey));
rsaCtx->priKeyData = (VoltRsaPrivateKey *)0;
rsaCtx->pubKeyData = (VoltRsaPublicKey *)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),
&(rsaCtx->tempKey));
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
rsaCtx->tempKey, VtKeyParamRSAPrivateSign, (Pointer)getKeyInfo);
if (status != 0)
break;
key = (VoltKeyObject *)(rsaCtx->tempKey);
getKeyData = (VoltRsaPrivateKey *)(key->keyData);
rsaCtx->priKeyData = getKeyData;
/* How big will the signature be? It depends on the key size.
*/
modLen = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
if (getKeyData->modulus != (VoltMpInt *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->GetBitLength (getKeyData->modulus, &modLen);
if (status != 0)
break;
}
if (modLen == 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->GetBitLength (getKeyData->prime1, &modLen);
if (status != 0)
break;
/* Use digestLen as a temp variable.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->GetBitLength (getKeyData->prime2, &digestLen);
if (status != 0)
break;
modLen += digestLen;
}
modLen = (modLen + 7) / 8;
*signatureSize = modLen;
/* The paddedBlockLen is the same size.
*/
signCtx->paddedBlockLen = modLen;
/* The dataToSignLen must be the appropriate length for the given
* digest.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetDigestLenFromAlg (
libCtx, signCtx->digestAlg, &digestLen, (unsigned int *)0);
if (status != 0)
break;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (dataToSignLen != digestLen)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (dataToSign == (unsigned char *)0)
break;
rsaCtx->priKeyData = getKeyData;
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "RSACheckSignatureInput", fnctLine, (char *)0)
return (status);
}
int RSASignData (
VoltAlgorithmObject *obj,
VoltKeyObject *key,
VtRandomObject random,
unsigned char *dataToSign,
unsigned int dataToSignLen,
unsigned char *signature,
unsigned int *sigLen
)
{
int status;
unsigned int sign, blockSize;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
VoltRsaSignCtx *rsaCtx = (VoltRsaSignCtx *)(signCtx->localSignCtx);
VoltMpIntCtx *mpCtx = key->mpCtx;
VoltMpInt *base = (VoltMpInt *)0;
VoltMpInt *result = (VoltMpInt *)0;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* For RSA, the input block size and the output block size are the
* same.
*/
blockSize = signCtx->paddedBlockLen;
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_RSA_SIGN, 3, 1)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->CreateMpInt ((Pointer)mpCtx, &base);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->OctetStringToMpInt (0, dataToSign, dataToSignLen, base);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->CreateMpInt ((Pointer)mpCtx, &result);
if (status != 0)
break;
/* If we have the CRT info, use it. If not, use the private
* exponent.
*/
if (rsaCtx->priKeyData->prime1 != (VoltMpInt *)0)
{
VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_RSA_SIGN, 3, 2)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModExpCRT (
base, rsaCtx->priKeyData->prime1, rsaCtx->priKeyData->prime2,
rsaCtx->priKeyData->expo1, rsaCtx->priKeyData->expo2,
rsaCtx->priKeyData->coeff, result);
if (status != 0)
break;
}
else
{
VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_RSA_SIGN, 3, 2)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModExp (
base, rsaCtx->priKeyData->priExpo, rsaCtx->priKeyData->modulus,
result);
if (status != 0)
break;
}
/* Get the data into the signature buffer. If the actual length is
* shorter than the required len, prepend 00 bytes.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->MpIntToOctetString (
result, &sign, signature, blockSize, sigLen);
if (status != 0)
break;
VOLT_CALL_SURRENDER (surrCtx, VT_SURRENDER_FNCT_RSA_SIGN, 3, 3)
if (*sigLen == blockSize)
break;
Z2Memmove (signature + (blockSize - *sigLen), signature, *sigLen);
Z2Memset (signature, 0, blockSize - *sigLen);
*sigLen = blockSize;
} while (0);
if (base != (VoltMpInt *)0)
mpCtx->DestroyMpInt (&base);
if (result != (VoltMpInt *)0)
mpCtx->DestroyMpInt (&result);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, 0,
(char *)0, "RSASignData", fnctLine, (char *)0)
return (status);
}
int RSAVerifyData (
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, modLen, resultLen, sign;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
VoltRsaSignCtx *rsaCtx = (VoltRsaSignCtx *)(signCtx->localSignCtx);
unsigned char *buffer = (unsigned char *)0;
VoltRsaPublicKey *getKeyData;
VtRSAPubKeyInfo *getKeyInfo;
VoltMpIntCtx *mpCtx;
VoltMpInt *base = (VoltMpInt *)0;
VoltMpInt *result = (VoltMpInt *)0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -