📄 p1t2pad.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 "cipher.h"
#include "p1pad.h"
#include "errorctx.h"
int VtPaddingPkcs1Type2 (
VtAlgorithmObject object,
VtPaddingInfo *info,
unsigned int flag
)
{
int status;
VoltAlgorithmObject *obj = (VoltAlgorithmObject *)object;
VoltCipherClassCtx *cipherCtx;
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_ASYMMETRIC_CIPHER.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_SET;
if (obj->algClass != VOLT_CLASS_ASYMMETRIC_CIPHER)
break;
/* We have an asymmetric cipher object, which means we have a
* CipherCtx.
*/
cipherCtx = (VoltCipherClassCtx *)(obj->classCtx);
/* This only works with RSA.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (cipherCtx->setState != VOLT_CIPHER_SET_STATE_RSA)
break;
cipherCtx->Pad = P1T2Pad;
cipherCtx->Unpad = P1T2Unpad;
obj->subAlg2 |= VOLT_SUB_ALG_P1_T2_PAD;
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VtPaddingPkcs1Type2", fnctLine, (char *)0)
return (status);
}
int P1T2Pad (
VoltAlgorithmObject *obj,
VtRandomObject random,
Pointer ctx,
unsigned char *block,
unsigned int inputLen,
unsigned int blockSize
)
{
int status;
unsigned int ffLen, offset;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VtRandomObject randomToUse;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* If there's no random object, get one from the libCtx.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NO_RANDOM_OBJECT;
randomToUse = random;
if (random == (VtRandomObject)0)
{
randomToUse = (VtRandomObject)VoltGetLibCtxInfo (
(VtLibCtx)libCtx, VOLT_LIB_CTX_INFO_TYPE_RANDOM);
if (randomToUse == (VtRandomObject)0)
break;
}
/* Make sure the random object is valid.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_RANDOM_OBJ;
if (VOLT_OBJECT_TYPE_NOT_EQUAL (randomToUse, VOLT_OBJECT_TYPE_RANDOM))
break;
/* P1 Type 2 padding looks like this
* 00 01 <random, non-zero bytes> 00 <data to encrypt>
* There must be at least 8 octets of random bytes.
* How long will the random bytess 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)
status = VT_ERROR_INVALID_INPUT_LENGTH;
ffLen = 3 + inputLen;
if (ffLen > blockSize)
break;
VOLT_SET_FNCT_LINE (fnctLine)
ffLen = blockSize - ffLen;
if (ffLen < 8)
break;
/* Move the data to encrypt to the end of the block.
*/
offset = blockSize - inputLen;
Z2Memmove (block + offset, block, inputLen);
/* The byte right before the data to encrypt is 00.
*/
block[offset - 1] = 0;
/* The first byte is 00, the next byte is 02.
*/
block[0] = 0;
block[1] = 2;
/* The rest of the bytes are random bytes
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGenerateRandomBytes (randomToUse, block + 2, ffLen);
if (status != 0)
break;
/* Make sure all the bytes are non-zero.
*/
offset = 2;
do
{
/* If the value is not zero, just move on to the next byte,
* unless this was the last byte.
*/
if (block[offset] != 0)
{
if (ffLen == 1)
break;
ffLen--;
offset++;
continue;
}
/* The byte is 00, generate a new one.
*/
status = VtGenerateRandomBytes (randomToUse, block + offset, 1);
if (status != 0)
break;
} while (1);
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "P1T1Pad", fnctLine, (char *)0)
return (status);
}
int P1T2Unpad (
VoltAlgorithmObject *obj,
Pointer ctx,
unsigned char *block,
unsigned int blockSize,
unsigned int *outputLen
)
{
int status;
unsigned int index, ffLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* To help avoid timing attacks, perform all checks.
*/
status = 0;
if ( (block[0] != 0) || (block[1] != 2) )
status = VT_ERROR_INVALID_PAD;
/* Keep checking bytes until we find the next 00 byte.
*/
index = 2;
ffLen = 0;
do
{
if ( (block[index] == 0) && (ffLen == 0) )
ffLen = index - 2;
index++;
} while (index < blockSize);
/* There must be at least 8 pad bytes.
*/
if (ffLen < 8)
status = VT_ERROR_INVALID_PAD;
/* Move the message block to the front.
*/
ffLen += 3;
Z2Memmove (block, block + ffLen, blockSize - ffLen);
*outputLen = blockSize - ffLen;
} while (0);
VOLT_SET_FNCT_LINE (fnctLine)
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "P1T1Unpad", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -