📄 p1t1pad.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 "p1pad.h"
#include "errorctx.h"
/* Based on the digestAlg, return a buffer containing the digestInfo.
* <p>This function will allocate the memory to hold the digestInfo,
* the caller must free that memory.
* <p>The function will also return the length the digest should be.
* <p>This routine will do no error checking, it is the responsibility
* of the caller not to make mistakes.
*/
static int VOLT_CALLING_CONV GetDigestInfoAlloc VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
unsigned int digestAlg,
unsigned char **digestInfo,
unsigned int *digestInfoLen,
unsigned int *digestLen
));
int VtPaddingPkcs1Type1 (
VtAlgorithmObject object,
VtPaddingInfo *info,
unsigned int flag
)
{
int status;
VoltAlgorithmObject *obj = (VoltAlgorithmObject *)object;
VoltSignClassCtx *signCtx;
VoltPaddingInfo *padInfo = (VoltPaddingInfo *)info;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Check the flag, it should be VOLT_PADDING_SET_TYPE_FLAG.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_PADDING_SET_TYPE_FLAG)
break;
/* The associated info should be a NULL pointer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (padInfo->info != (Pointer)0)
break;
/* Check the class of the object. It should be VOLT_CLASS_SIGNATURE
* or VOLT_CLASS_VERIFY.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_SET;
if ((obj->algClass & (VOLT_CLASS_SIGNATURE | VOLT_CLASS_VERIFY)) == 0)
break;
/* We have a signature object, which means we have a SignCtx.
*/
signCtx = (VoltSignClassCtx *)(obj->classCtx);
/* This only works with RSA.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ((signCtx->algorithm & VOLT_SIGNATURE_ALG_RSA) == 0)
break;
signCtx->Pad = P1T1Pad;
signCtx->Unpad = P1T1Unpad;
obj->subAlg2 |= VOLT_SUB_ALG_P1_T1_PAD;
status = 0;
} while (0);
/* If something went wrong, indicate that this object is not usable.
*/
if (status != 0)
obj->state = VOLT_STATE_ERROR;
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VtPaddingPkcs1Type1", fnctLine, (char *)0)
return (status);
}
int P1T1Pad (
VoltAlgorithmObject *obj,
VtRandomObject random,
Pointer ctx,
unsigned char *block,
unsigned int inputLen,
unsigned int blockSize
)
{
int status;
unsigned int ffLen, offset, digestInfoLen, digestLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
unsigned char *digestInfo = (unsigned char *)0;
VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = GetDigestInfoAlloc (
libCtx, signCtx->digestAlg, &digestInfo, &digestInfoLen, &digestLen);
if (status != 0)
break;
/* Make sure the inputLen is the digest length.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (inputLen != digestLen)
break;
/* P1 Type 1 padding looks like this
* 00 01 ff ff ... ff 00 <digestInfo> <digest>
* There must be at least 8 octets of ff.
* How long will the ff's be?
* First, count the number of bytes that will make up everything
* else, make sure that's not longer than blockSize.
*/
VOLT_SET_FNCT_LINE (fnctLine)
ffLen = digestInfoLen + digestLen + 3;
if (ffLen > blockSize)
break;
VOLT_SET_FNCT_LINE (fnctLine)
ffLen = blockSize - ffLen;
if (ffLen < 8)
break;
/* Move the digest to the end of the block.
*/
offset = blockSize - inputLen;
Z2Memmove (block + offset, block, inputLen);
/* Copy the digestInfo.
*/
offset -= digestInfoLen;
Z2Memcpy (block + offset, digestInfo, digestInfoLen);
/* The byte right before the digestInfo is 00.
*/
block[offset - 1] = 0;
/* The first byte is 00, the next byte is 01.
*/
block[0] = 0;
block[1] = 1;
/* The rest of the bytes are 0xff
*/
Z2Memset (block + 2, 0xff, ffLen);
status = 0;
} while (0);
if (digestInfo != (unsigned char *)0)
Z2Free (digestInfo);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "P1T1Pad", fnctLine, (char *)0)
return (status);
}
int P1T1Unpad (
VoltAlgorithmObject *obj,
Pointer ctx,
unsigned char *block,
unsigned int blockSize,
unsigned int *outputLen
)
{
int status;
unsigned int index, ffLen, digestInfoLen, digestLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
unsigned char *digestInfo = (unsigned char *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = GetDigestInfoAlloc (
libCtx, signCtx->digestAlg, &digestInfo, &digestInfoLen, &digestLen);
if (status != 0)
break;
/* How many 0xff bytes should there be? While we're computing that,
* make sure blockLen is reasonable.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
ffLen = digestInfoLen + digestLen + 3;
if (ffLen > blockSize)
break;
VOLT_SET_FNCT_LINE (fnctLine)
/* The next section of code is going to check the pad bytes. If
* they're wrong, we'll set status to an error, but we'll continue
* the check. After the checks, we'll move the digest to the front
* (the Unpad). This way, we can return an error if there is an
* error, but still return the digest, in case the caller wants to
* ignore the error.
*/
status = 0;
/* PKCS #1 says there must be at leas 8 ff bytes.
*/
ffLen = blockSize - ffLen;
if (ffLen < 8)
status = VT_ERROR_INVALID_PAD;
/* The first two bytes must be 00 01.
*/
if ( (block[0] != 0) || (block[1] != 1) )
status = VT_ERROR_INVALID_PAD;
/* The next ffLen bytes should be 0xff.
*/
for (index = 2; index < ffLen + 2; ++index)
if (block[index] != 0xff)
break;
/* If we broke early, there was an error.
*/
if (index < (ffLen + 2))
status = VT_ERROR_INVALID_PAD;
/* The next byte should be 00.
*/
if (block[ffLen + 2] != 0)
status = VT_ERROR_INVALID_PAD;
/* The next padCtx->digestInfoLen bytes should be the digestInfo.
*/
if (Z2Memcmp (
block + ffLen + 3, digestInfo, digestInfoLen) != 0)
status = VT_ERROR_INVALID_PAD;
/* Move the digest to the front.
*/
Z2Memmove (
block, block + ffLen + 3 + digestInfoLen, digestLen);
*outputLen = digestLen;
} while (0);
if (digestInfo != (unsigned char *)0)
Z2Free (digestInfo);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "P1T1Unpad", fnctLine, (char *)0)
return (status);
}
static int GetDigestInfoAlloc (
VoltLibCtx *libCtx,
unsigned int digestAlg,
unsigned char **digestInfo,
unsigned int *digestInfoLen,
unsigned int *digestLen
)
{
int status;
unsigned int infoLen;
unsigned char *info;
unsigned char *buffer = (unsigned char *)0;
unsigned char md5Info[VOLT_MD5_DIGEST_INFO_LEN] =
{ VOLT_MD5_DIGEST_INFO };
unsigned char sha1Info[VOLT_SHA1_DIGEST_INFO_LEN] =
{ VOLT_SHA1_DIGEST_INFO };
unsigned char sha224Info[VOLT_SHA224_DIGEST_INFO_LEN] =
{ VOLT_SHA224_DIGEST_INFO };
unsigned char sha256Info[VOLT_SHA256_DIGEST_INFO_LEN] =
{ VOLT_SHA256_DIGEST_INFO };
unsigned char sha384Info[VOLT_SHA384_DIGEST_INFO_LEN] =
{ VOLT_SHA384_DIGEST_INFO };
unsigned char sha512Info[VOLT_SHA512_DIGEST_INFO_LEN] =
{ VOLT_SHA512_DIGEST_INFO };
VOLT_DECLARE_FNCT_LINE (fnctLine)
status = 0;
switch (digestAlg)
{
case VT_DIGEST_ALG_MD5:
info = md5Info;
infoLen = VOLT_MD5_DIGEST_INFO_LEN;
*digestLen = 16;
break;
case VT_DIGEST_ALG_SHA1:
info = sha1Info;
infoLen = VOLT_SHA1_DIGEST_INFO_LEN;
*digestLen = 20;
break;
case VT_DIGEST_ALG_SHA224:
info = sha224Info;
infoLen = VOLT_SHA224_DIGEST_INFO_LEN;
*digestLen = 28;
break;
case VT_DIGEST_ALG_SHA256:
info = sha256Info;
infoLen = VOLT_SHA256_DIGEST_INFO_LEN;
*digestLen = 32;
break;
case VT_DIGEST_ALG_SHA384:
info = sha384Info;
infoLen = VOLT_SHA384_DIGEST_INFO_LEN;
*digestLen = 48;
break;
case VT_DIGEST_ALG_SHA512:
info = sha512Info;
infoLen = VOLT_SHA512_DIGEST_INFO_LEN;
*digestLen = 64;
break;
default:
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
}
/* If we have a supported digest, allocate the buffer to hold the
* digestInfo and copy the data.
*/
if (status == 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (infoLen, 0);
if (buffer != (unsigned char *)0)
{
Z2Memcpy (buffer, info, infoLen);
*digestInfo = buffer;
*digestInfoLen = infoLen;
return (0);
}
}
/* If we reach this point in the code, there was an error.
*/
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR_INFO (
libCtx, 0, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "GetDigestInfoAlloc", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -