📄 opensslbnwrap.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "mpint.h"
#include "opensslbnwrap.h"
#include "errorctx.h"
#include "openssl/bn.h"
#include "openssl/err.h"
int OpenSSLBnWrapCreateMpInt (
Pointer mpIntCtx,
VoltMpInt **newInt
)
{
int status;
unsigned int bufferSize;
unsigned char *buffer = (unsigned char *)0;
VoltMpIntCtx *mpCtx = (VoltMpIntCtx *)mpIntCtx;
VoltLibCtx *libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);
VoltMpInt *mpInt;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Allocate space for the VoltMpInt.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = sizeof (VoltMpInt);
buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
Z2Memset (buffer, 0, bufferSize);
/* Position the pointers.
*/
mpInt = (VoltMpInt *)buffer;
mpInt->mpCtx = (VtMpIntCtx)mpCtx;
/* The mpInt field of the VoltMpInt will be a BIGNUM *.
*/
VOLT_SET_FNCT_LINE (fnctLine)
mpInt->mpInt = (Pointer)BN_new ();
if (mpInt->mpInt == (Pointer)0)
break;
/* Initialize to zero.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (BN_set_word ((BIGNUM *)(mpInt->mpInt), 0) == 0)
break;
*newInt = (VoltMpInt *)mpInt;
status = 0;
} while (0);
/* If successful, just return.
*/
if (status == 0)
return (0);
/* If error, free memory.
*/
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR (
libCtx, status, VT_ERROR_TYPE_PRIMARY, fnctLine,
"OpenSSLBnWrapCreateMpInt", (char *)0)
return (status);
}
int OpenSSLBnWrapDestroyMpInt (
VoltMpInt **theInt
)
{
VoltMpIntCtx *mpCtx;
VoltLibCtx *libCtx;
/* Call the clear function for the mpz, then free up the MpInt's
* memory.
*/
if (theInt == (VoltMpInt **)0)
return (0);
if (*theInt == (VoltMpInt *)0)
return (0);
/* Destroy the BIGNUM in the mpInt.
*/
if ((*theInt)->mpInt != (Pointer)0)
BN_clear_free ((BIGNUM *)((*theInt)->mpInt));
mpCtx = (VoltMpIntCtx *)((*theInt)->mpCtx);
libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);
Z2Free (*theInt);
*theInt = (VoltMpInt *)0;
return (0);
}
int OpenSSLBnWrapOctetStringToMpInt (
unsigned int sign,
unsigned char *sourceOctetString,
unsigned int sourceOctetStringLen,
VoltMpInt *destInt
)
{
int status;
BIGNUM *bnTarget, *dummyBn;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If NULL, we can't log an error, no libCtx.
*/
if (destInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
do
{
/* Check the arguments.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (sourceOctetString == (unsigned char *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (sourceOctetStringLen == 0)
break;
bnTarget = (BIGNUM *)(destInt->mpInt);
/* Call the bn version.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
dummyBn = BN_bin2bn (
sourceOctetString, (int)sourceOctetStringLen, bnTarget);
/* If it worked, the result is the same as the input.
* If they are different, there was some error, likely memory.
*/
if (dummyBn != bnTarget)
break;
/* To set the sign, we can't treat the bn as an opaque type. So
* long as the definition of BIGNUM does not change, this will work.
* If sign is 0, the number is positive. Otherwise, the number is
* negative. Inside a BIGNUM, if neg is 0, the number is positive,
* if neg is 1, the number is negative.
*/
bnTarget->neg = 1;
if (sign == 0)
bnTarget->neg = 0;
status = 0;
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, destInt->mpCtx->voltObject.libraryCtx, status,
VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapOctetStringToMpInt",
(char *)0)
return (status);
}
int OpenSSLBnWrapIntToMpInt (
int signCheck,
int sourceValue,
VoltMpInt *destInt
)
{
int status, posVal;
BIGNUM *bnTarget;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If NULL, we can't log an error, no libCtx.
*/
if (destInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
bnTarget = (BIGNUM *)(destInt->mpInt);
do
{
status = VT_ERROR_MEMORY;
/* If signCheck is 0, the sourceValue is an unsigned int.
*/
if (signCheck == 0)
{
/* This function returns 0 for failure and presumably 1 for success.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (BN_set_word (bnTarget, (BN_ULONG)sourceValue) != 0)
status = 0;
}
else
{
/* If signCheck is not 0, the sourceValue is a signed int.
*/
posVal = -sourceValue;
if (sourceValue >= 0)
posVal = sourceValue;
/* This function returns 0 for failure.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (BN_set_word (bnTarget, (BN_ULONG)posVal) == 0)
break;
/* To set the sign, we can't treat the bn as an opaque type. So
* long as the definition of BIGNUM does not change, this will work.
* If sign is 0, the number is positive. Otherwise, the number is
* negative. Inside a BIGNUM, if neg is 0, the number is positive,
* if neg is 1, the number is negative.
*/
bnTarget->neg = 1;
if (sourceValue >= 0)
bnTarget->neg = 0;
status = 0;
}
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, destInt->mpCtx->voltObject.libraryCtx, status,
VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapIntToMpInt", (char *)0)
return (status);
}
int OpenSSLBnWrapMpIntToInt (
VoltMpInt *sourceInt,
int signCheck,
int *destValue
)
{
int status, returnValSigned;
unsigned int returnValUnsigned;
BN_ULONG result;
BIGNUM *srcBn;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If NULL, we can't log an error, no libCtx.
*/
if (sourceInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
srcBn = (BIGNUM *)(sourceInt->mpInt);
do
{
/* Check the arguments.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (destValue == (int *)0)
break;
*destValue = 0;
result = BN_get_word (srcBn);
/* If the return is BN_MASK2, the value was too big to fit into the
* BN_ULONG. If not, we have an answer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MP_INT_RANGE;
if (result == BN_MASK2)
break;
/* We have the answer as a BN_ULONG, get it as an unsigned int.
*/
returnValUnsigned = (unsigned int)result;
/* Make sure the conversion from BN_ULONG to unsigned int did not
* lose any precision.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (result != (BN_ULONG)returnValUnsigned)
break;
/* If signCheck is 0, the caller wanted the value as an unsigned
* int.
*/
if (signCheck == 0)
{
*destValue = (int)returnValUnsigned;
status = 0;
break;
}
/* The caller wants a signed int.
* First, check to see if the value fits into a signed int. If
* the value is negative, it was too big.
*/
VOLT_SET_FNCT_LINE (fnctLine)
returnValSigned = (int)returnValUnsigned;
if (returnValSigned < 0)
break;
/* To get the sign, we can't treat the bn as an opaque type. So
* long as the definition of BIGNUM does not change, this will
* work. Inside a BIGNUM, if neg is 0, the number is positive,
* if neg is 1, the number is negative.
*/
*destValue = returnValSigned;
if (srcBn->neg != 0)
*destValue = -returnValSigned;
status = 0;
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, sourceInt->mpCtx->voltObject.libraryCtx, status,
VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapMpIntToInt", (char *)0)
return (status);
}
int OpenSSLBnWrapMpIntToMpInt (
VoltMpInt *sourceInt,
VoltMpInt *destInt
)
{
BIGNUM *retVal;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If NULL, we can't log an error, no libCtx.
* We could check for one NULL, the other not, but this is the kind
* of error an app expects not to log.
*/
if ( (sourceInt == (VoltMpInt *)0) || (destInt == (VoltMpInt *)0) )
return (VT_ERROR_NULL_ARG);
/* If successful, this function returns the destination BIGNUM.
* If the return is NULL, error. Probably the only error possible is
* memory.
*/
VOLT_SET_FNCT_LINE (fnctLine)
retVal = BN_copy ((BIGNUM *)(destInt->mpInt), (BIGNUM *)(sourceInt->mpInt));
if (retVal != (BIGNUM *)0)
return (0);
VOLT_LOG_ERROR (
sourceInt->mpCtx->voltObject.libraryCtx, VT_ERROR_MEMORY,
VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapMpIntToMpInt", (char *)0)
return (VT_ERROR_MEMORY);
}
int OpenSSLBnWrapMpIntToOctetString (
VoltMpInt *sourceInt,
unsigned int *sign,
unsigned char *destBuf,
unsigned int bufferSize,
unsigned int *destLen
)
{
int status;
unsigned int bitLen, octLen;
BIGNUM *sourceBn;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If NULL, we can't log an error, no libCtx.
*/
if (sourceInt == (VoltMpInt *)0)
return (VT_ERROR_NULL_ARG);
sourceBn = (BIGNUM *)(sourceInt->mpInt);
do
{
/* Check the arguments.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if ( (sign == (unsigned int *)0) || (destLen == (unsigned int *)0) )
break;
if (destBuf == (unsigned char *)0)
bufferSize = 0;
/* To get the sign, we can't treat the bn as an opaque type. So long
* as the definition of BIGNUM does not change, this will work.
* Inside a BIGNUM, if neg is 0, the number is positive, if neg is 1,
* the number is negative.
*/
*sign = 1;
if (sourceBn->neg == 0)
*sign = 0;
/* How big does the buffer need to be?
*/
bitLen = (unsigned int)BN_num_bits (sourceBn);
octLen = 1;
if (bitLen != 0)
octLen = (bitLen + 7) / 8;
/* Is the buffer big enough?
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
*destLen = octLen;
if (bufferSize < octLen)
break;
/* If bitLen is 0, the value of the BIGNUM is 0. If bitLen is not
* 0, call the BN function to get the octet string.
*/
destBuf[0] = 0;
if (bitLen != 0)
octLen = BN_bn2bin (sourceBn, destBuf);
status = 0;
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, sourceInt->mpCtx->voltObject.libraryCtx, status,
VT_ERROR_TYPE_PRIMARY, fnctLine, "OpenSSLBnWrapMpIntToOctetString",
(char *)0)
return (status);
}
int OpenSSLBnWrapCompare (
VoltMpInt *leftInt,
VoltMpInt *rightInt,
int *result
)
{
int bnResult;
VOLT_DECLARE_FNCT_LINE (fnctLine)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -