diff options
Diffstat (limited to 'lib/dns/sec/dnssafe/ahrsaenc.c')
-rw-r--r-- | lib/dns/sec/dnssafe/ahrsaenc.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/lib/dns/sec/dnssafe/ahrsaenc.c b/lib/dns/sec/dnssafe/ahrsaenc.c new file mode 100644 index 00000000..307d1fd8 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaenc.c @@ -0,0 +1,241 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AH_RSAEncryption; +#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahrsaenc.h" + +static int AH_RSAEncryptionInitHelper PROTO_LIST ((AH_RSAEncryption *, int)); + +static AHEncryptDecryptVTable V_TABLE = { + AH_RSAEncryptionDestructor, AH_RSAEncryptionGetBlockLen, + AH_RSAEncryptionEncryptInit, AH_RSAEncryptionDecryptInit, + AH_RSAEncryptionUpdate, AH_RSAEncryptionUpdate, + AH_RSAEncryptionEncryptFinal, AH_RSAEncryptionDecryptFinal +}; + +void AH_RSAEncryptionConstructor1 (handler, infoType) +AH_RSAEncryption *handler; +struct B_AlgorithmInfoType *infoType; +{ + /* Construct base class with the infoType. Assume info is NULL_PTR. */ + AHChooseEncryptConstructor2 + (&handler->chooseEncryptDecrypt, infoType, NULL_PTR); + + T_memset ((POINTER)&handler->z, 0, sizeof (handler->z)); + /* Set the AHEncryptDecrypt vTable, but don't set the RSAEncryption vTable + since it is pure virtual. */ + handler->chooseEncryptDecrypt.encryptDecrypt.vTable = &V_TABLE; +} + +void AH_RSAEncryptionDestructor (handler) +AH_RSAEncryption *handler; +{ + T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen); + T_free ((POINTER)handler->z.block); + + /* Call base class destructor */ + AHChooseEncryptDestructor (handler); +} + +int AH_RSAEncryptionGetBlockLen (handler, blockLen) +AH_RSAEncryption *handler; +unsigned int *blockLen; +{ +UNUSED_ARG (handler) +UNUSED_ARG (blockLen) + return (BE_NOT_SUPPORTED); +} + +int AH_RSAEncryptionEncryptInit (handler, key, chooser, surrenderContext) +AH_RSAEncryption *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AHChooseEncryptEncryptInit + (handler, key, chooser, surrenderContext)) != 0) + return (status); + + return (AH_RSAEncryptionInitHelper (handler, 1)); +} + +int AH_RSAEncryptionDecryptInit (handler, key, chooser, surrenderContext) +AH_RSAEncryption *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AHChooseEncryptDecryptInit + (handler, key, chooser, surrenderContext)) != 0) + return (status); + + return (AH_RSAEncryptionInitHelper (handler, 0)); +} + +/* Accumulate into the z.block. + */ +int AH_RSAEncryptionUpdate + (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +AH_RSAEncryption *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (partOut) +UNUSED_ARG (maxPartOutLen) +UNUSED_ARG (randomAlgorithm) +UNUSED_ARG (surrenderContext) + *partOutLen = 0; + + if (handler->_inputLen + partInLen > handler->_maxInputLen) + return (BE_INPUT_LEN); + T_memcpy + ((POINTER)(handler->z.block + handler->_inputLen), (POINTER)partIn, + partInLen); + handler->_inputLen += partInLen; + return (0); +} + +int AH_RSAEncryptionEncryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AH_RSAEncryption *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int dummyPartOutLen; + + /* Encode methodContext in place. */ + if ((status = (*handler->vTable->EncodeBlock) + (handler, randomAlgorithm, surrenderContext)) != 0) + return (status); + + /* This should not return BE_INPUT_DATA since it is well-formatted. */ + if ((status = AHChooseEncryptEncryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, handler->z.block, + handler->z.blockLen, (B_Algorithm *)NULL_PTR, surrenderContext)) != 0) + return (status); + + /* Expect final to return zero bytes. */ + if ((status = AHChooseEncryptEncryptFinal + (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0, + (B_Algorithm *)NULL_PTR, surrenderContext)) != 0) + return (status); + + /* Restart the handle for new input. */ + handler->_inputLen = 0; + return (0); +} + +int AH_RSAEncryptionDecryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AH_RSAEncryption *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + ITEM output; + int status; + unsigned int decryptedLen, dummyPartOutLen; + +UNUSED_ARG (randomAlgorithm) + /* Decrypt block in place. The block lenghts are already within limits. + */ + if ((status = AHChooseEncryptDecryptUpdate + (handler, handler->z.block, &decryptedLen, handler->z.blockLen, + handler->z.block, handler->_inputLen, (B_Algorithm *)NULL_PTR, + surrenderContext)) != 0) + return (status); + /* Expect final to return zero bytes. */ + if ((status = AHChooseEncryptDecryptFinal + (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0, + (B_Algorithm *)NULL_PTR, surrenderContext)) != 0) + return (status); + + /* Restart the handle for new input. */ + handler->_inputLen = 0; + + /* Now decode the block and copy the result to the partOut. + */ + if ((status = (*handler->vTable->DecodeBlock) + (handler, &output, decryptedLen)) != 0) + return (status); + + if (output.len > handler->z.blockLen - 11) + /* This implies that the block was encrypted with less than + 8 bytes of padding */ + return (BE_INPUT_DATA); + + if ((*partOutLen = output.len) > maxPartOutLen) + return (BE_OUTPUT_LEN); + T_memcpy ((POINTER)partOut, (POINTER)output.data, output.len); + + return (0); +} + +static int AH_RSAEncryptionInitHelper (handler, encryptFlag) +AH_RSAEncryption *handler; +int encryptFlag; +{ + int status; + unsigned int newBlockLen; + + if ((status = AHChooseEncryptGetBlockLen (handler, &newBlockLen)) != 0) + return (status); + + if (newBlockLen < 12) + /* PKCS Requires at least 12 bytes of modulus */ + return (BE_NOT_SUPPORTED); + + /* During encrypt, this will ensure that there are 8 bytes of padding. + During decrypt, the DecodeBlock procedure must check that the block + was encrypted with 8 bytes of padding. + */ + handler->_maxInputLen = encryptFlag ? (newBlockLen - 11) : newBlockLen; + + handler->_inputLen = 0; + + /* Zeroize old block and realloc to new size. + */ + T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen); + if ((handler->z.block = (unsigned char *)T_realloc + ((POINTER)handler->z.block, newBlockLen)) + == (unsigned char *)NULL_PTR) { + handler->z.blockLen = 0; + return (BE_ALLOC); + } + + handler->z.blockLen = newBlockLen; + return (0); +} + |