📄 r_enhanc.c
字号:
/* R_ENHANC.C - cryptographic enhancements for RSAREF
*/
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
Inc., created 1991. All rights reserved.
*/
#include "global.h"
#include "rsaref.h"
#include "r_random.h"
#include "rsa.h"
/* DigestInfo encoding is DIGEST_INFO_A, then 2 or 5 (for MD2/MD5),
then DIGEST_INFO_B, then 16-byte message digest.
*/
static unsigned char DIGEST_INFO_A[] = {
0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x02
};
#define DIGEST_INFO_A_LEN sizeof (DIGEST_INFO_A)
static unsigned char DIGEST_INFO_B[] = { 0x05, 0x00, 0x04, 0x10 };
#define DIGEST_INFO_B_LEN sizeof (DIGEST_INFO_B)
#define DIGEST_INFO_LEN (DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN + 16)
static unsigned char *PADDING[] = {
(unsigned char *)"", (unsigned char *)"\001", (unsigned char *)"\002\002",
(unsigned char *)"\003\003\003", (unsigned char *)"\004\004\004\004",
(unsigned char *)"\005\005\005\005\005",
(unsigned char *)"\006\006\006\006\006\006",
(unsigned char *)"\007\007\007\007\007\007\007",
(unsigned char *)"\010\010\010\010\010\010\010\010"
};
#define MAX_ENCRYPTED_KEY_LEN MAX_RSA_MODULUS_LEN
static void R_EncodeDigestInfo PROTO_LIST
((unsigned char *, int, unsigned char *));
static void EncryptPEMUpdateFinal PROTO_LIST
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
unsigned int));
static int DecryptPEMUpdateFinal PROTO_LIST
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
unsigned int));
static int CipherInit PROTO_LIST
((R_ENVELOPE_CTX *, int, unsigned char *, unsigned char *, int));
static void CipherUpdate PROTO_LIST
((R_ENVELOPE_CTX *, unsigned char *, unsigned char *, unsigned int));
static void CipherRestart PROTO_LIST ((R_ENVELOPE_CTX *));
int R_DigestInit (context, digestAlgorithm)
R_DIGEST_CTX *context; /* new context */
int digestAlgorithm; /* message-digest algorithm */
{
context->digestAlgorithm = digestAlgorithm;
switch (digestAlgorithm) {
case DA_MD2:
MD2Init (&context->context.md2);
break;
case DA_MD5:
MD5Init (&context->context.md5);
break;
default:
return (RE_DIGEST_ALGORITHM);
}
return (0);
}
int R_DigestUpdate (context, partIn, partInLen)
R_DIGEST_CTX *context; /* context */
unsigned char *partIn; /* next data part */
unsigned int partInLen; /* length of next data part */
{
if (context->digestAlgorithm == DA_MD2)
MD2Update (&context->context.md2, partIn, partInLen);
else
MD5Update (&context->context.md5, partIn, partInLen);
return (0);
}
int R_DigestFinal (context, digest, digestLen)
R_DIGEST_CTX *context; /* context */
unsigned char *digest; /* message digest */
unsigned int *digestLen; /* length of message digest */
{
*digestLen = 16;
if (context->digestAlgorithm == DA_MD2)
MD2Final (digest, &context->context.md2);
else
MD5Final (digest, &context->context.md5);
return (0);
}
int R_SignInit (context, digestAlgorithm)
R_SIGNATURE_CTX *context; /* new context */
int digestAlgorithm; /* message-digest algorithm */
{
return (R_DigestInit (&context->digestContext, digestAlgorithm));
}
int R_SignUpdate (context, partIn, partInLen)
R_SIGNATURE_CTX *context; /* context */
unsigned char *partIn; /* next data part */
unsigned int partInLen; /* length of next data part */
{
return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
}
int R_SignFinal (context, signature, signatureLen, privateKey)
R_SIGNATURE_CTX *context; /* context */
unsigned char *signature; /* signature */
unsigned int *signatureLen; /* length of signature */
R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
{
int status;
unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN];
unsigned int digestLen;
do {
if ((status = R_DigestFinal (&context->digestContext, digest, &digestLen))
!= 0)
break;
R_EncodeDigestInfo
(digestInfo, context->digestContext.digestAlgorithm, digest);
if (RSAPrivateEncrypt
(signature, signatureLen, digestInfo, DIGEST_INFO_LEN, privateKey)
!= 0) {
status = RE_PRIVATE_KEY;
break;
}
/* Reset for another verification. Assume Init won't fail */
R_DigestInit
(&context->digestContext, context->digestContext.digestAlgorithm);
} while (0);
/* Zeroize potentially sensitive information.
*/
R_memset ((POINTER)digest, 0, sizeof (digest));
R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
return (status);
}
int R_VerifyInit (context, digestAlgorithm)
R_SIGNATURE_CTX *context; /* new context */
int digestAlgorithm; /* message-digest algorithm */
{
return (R_DigestInit (&context->digestContext, digestAlgorithm));
}
int R_VerifyUpdate (context, partIn, partInLen)
R_SIGNATURE_CTX *context; /* context */
unsigned char *partIn; /* next data part */
unsigned int partInLen; /* length of next data part */
{
return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
}
int R_VerifyFinal (context, signature, signatureLen, publicKey)
R_SIGNATURE_CTX *context; /* context */
unsigned char *signature; /* signature */
unsigned int signatureLen; /* length of signature */
R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
{
int status;
unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN],
originalDigestInfo[MAX_SIGNATURE_LEN];
unsigned int originalDigestInfoLen, digestLen;
if (signatureLen > MAX_SIGNATURE_LEN)
return (RE_LEN);
status = 0;
do {
if ((status = R_DigestFinal (&context->digestContext, digest, &digestLen))
!= 0)
break;
R_EncodeDigestInfo
(digestInfo, context->digestContext.digestAlgorithm, digest);
if (RSAPublicDecrypt
(originalDigestInfo, &originalDigestInfoLen, signature, signatureLen,
publicKey) != 0) {
status = RE_PUBLIC_KEY;
break;
}
if ((originalDigestInfoLen != DIGEST_INFO_LEN) ||
(R_memcmp
((POINTER)originalDigestInfo, (POINTER)digestInfo,
DIGEST_INFO_LEN))) {
status = RE_SIGNATURE;
break;
}
/* Reset for another verification. Assume Init won't fail */
R_DigestInit
(&context->digestContext, context->digestContext.digestAlgorithm);
} while (0);
/* Zeroize potentially sensitive information.
*/
R_memset ((POINTER)digest, 0, sizeof (digest));
R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
R_memset ((POINTER)originalDigestInfo, 0, sizeof (originalDigestInfo));
return (status);
}
/* Caller must ASCII recode the encrypted keys if desired.
*/
int R_SealInit
(context, encryptedKeys, encryptedKeyLens, iv, publicKeyCount, publicKeys,
encryptionAlgorithm, randomStruct)
R_ENVELOPE_CTX *context; /* new context */
unsigned char **encryptedKeys; /* encrypted keys */
unsigned int *encryptedKeyLens; /* lengths of encrypted keys */
unsigned char iv[8]; /* initialization vector */
unsigned int publicKeyCount; /* number of public keys */
R_RSA_PUBLIC_KEY **publicKeys; /* public keys */
int encryptionAlgorithm; /* data encryption algorithm */
R_RANDOM_STRUCT *randomStruct; /* random structure */
{
int status;
unsigned char key[24];
unsigned int keyLen, i;
do {
context->encryptionAlgorithm = encryptionAlgorithm;
keyLen = (encryptionAlgorithm == EA_DES_CBC) ? 8 : 24;
if ((status = R_GenerateBytes (key, keyLen, randomStruct)) != 0)
break;
if ((status = R_GenerateBytes (iv, 8, randomStruct)) != 0)
break;
if (encryptionAlgorithm == EA_DES_EDE2_CBC)
/* Make both E keys the same */
R_memcpy ((POINTER)(key + 16), (POINTER)key, 8);
if ((status = CipherInit (context, encryptionAlgorithm, key, iv, 1)) != 0)
break;
for (i = 0; i < publicKeyCount; ++i) {
if (RSAPublicEncrypt
(encryptedKeys[i], &encryptedKeyLens[i], key, keyLen,
publicKeys[i], randomStruct)) {
status = RE_PUBLIC_KEY;
break;
}
}
if (status != 0)
break;
context->bufferLen = 0;
} while (0);
/* Zeroize sensitive information.
*/
R_memset ((POINTER)key, 0, sizeof (key));
return (status);
}
/* Assume partOut buffer is at least partInLen + 7, since this may flush
buffered input.
*/
int R_SealUpdate (context, partOut, partOutLen, partIn, partInLen)
R_ENVELOPE_CTX *context; /* context */
unsigned char *partOut; /* next encrypted data part */
unsigned int *partOutLen; /* length of next encrypted data part */
unsigned char *partIn; /* next data part */
unsigned int partInLen; /* length of next data part */
{
unsigned int tempLen;
tempLen = 8 - context->bufferLen;
if (partInLen < tempLen) {
/* Just accumulate into buffer.
*/
R_memcpy
((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
partInLen);
context->bufferLen += partInLen;
*partOutLen = 0;
return (0);
}
/* Fill the buffer and encrypt.
*/
R_memcpy
((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
tempLen);
CipherUpdate (context, partOut, context->buffer, 8);
partIn += tempLen;
partInLen -= tempLen;
partOut += 8;
*partOutLen = 8;
/* Encrypt as many 8-byte blocks as possible.
*/
tempLen = 8 * (partInLen / 8);
CipherUpdate (context, partOut, partIn, tempLen);
partIn += tempLen;
partInLen -= tempLen;
*partOutLen += tempLen;
/* Length is now less than 8, so copy remainder to buffer.
*/
R_memcpy
((POINTER)context->buffer, (POINTER)partIn,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -