#define EVP_PKEY_OP_ENCRYPT 8
#define EVP_PKEY_OP_DECRYPT 9
+#define EVP_PKEY_CTRL_MD_NID 1
+
+#define EVP_PKEY_ALG_CTRL 0x1000
+
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
#define EVP_R_EXPECTING_A_EC_KEY 142
#define EVP_R_INITIALIZATION_ERROR 134
#define EVP_R_INPUT_NOT_INITIALIZED 111
+#define EVP_R_INVALID_DIGEST 152
#define EVP_R_INVALID_KEY_LENGTH 130
#define EVP_R_INVALID_OPERATION 148
#define EVP_R_IV_TOO_LARGE 102
{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"},
{ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"},
{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
+{ERR_REASON(EVP_R_INVALID_DIGEST) ,"invalid digest"},
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
{ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"},
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
+ if (!strcmp(name, "digest"))
+ {
+ const EVP_MD *md;
+ if (!value || !(md = EVP_get_digestbyname(value)))
+ {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_MD_NID,
+ EVP_MD_type(md), NULL);
+ }
return ctx->pmeth->ctrl_str(ctx, name, value);
}
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
pad, NULL)
-#define EVP_PKEY_CTRL_RSA_PADDING 1
+#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
#define RSA_PKCS1_PADDING 1
#define RSA_SSLV23_PADDING 2
/* Error codes for the RSA functions. */
/* Function codes. */
+#define RSA_F_CHECK_PADDING_NID 140
#define RSA_F_MEMORY_LOCK 100
+#define RSA_F_PKEY_RSA_VERIFYRECOVER 141
#define RSA_F_RSA_BUILTIN_KEYGEN 129
#define RSA_F_RSA_CHECK_KEY 123
#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101
#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125
#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123
#define RSA_R_FIRST_OCTET_INVALID 133
+#define RSA_R_INVALID_DIGEST 105
#define RSA_R_INVALID_HEADER 137
#define RSA_R_INVALID_MESSAGE_LENGTH 131
#define RSA_R_INVALID_PADDING 138
+#define RSA_R_INVALID_PADDING_MODE 141
#define RSA_R_INVALID_TRAILER 139
+#define RSA_R_INVALID_X931_DIGEST 142
#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126
#define RSA_R_KEY_SIZE_TOO_SMALL 120
#define RSA_R_LAST_OCTET_INVALID 134
static ERR_STRING_DATA RSA_str_functs[]=
{
+{ERR_FUNC(RSA_F_CHECK_PADDING_NID), "CHECK_PADDING_NID"},
{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"},
+{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
-{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_PRINT_FP"},
{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
{ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"},
+{ERR_REASON(RSA_R_INVALID_DIGEST) ,"invalid digest"},
{ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"},
{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
{ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"},
+{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"},
{ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"},
+{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"},
{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/rsa.h>
+#include <openssl/evp.h>
#include "evp_locl.h"
+extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *rm, unsigned int *prm_len,
+ unsigned char *sigbuf, unsigned int siglen,
+ RSA *rsa);
+
/* RSA pkey context structure */
typedef struct
BIGNUM *pub_exp;
/* RSA padding mode */
int pad_mode;
+ /* nid for message digest */
+ int md_nid;
+ /* Temp buffer */
+ unsigned char *tbuf;
} RSA_PKEY_CTX;
static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
rctx->nbits = 1024;
rctx->pub_exp = NULL;
rctx->pad_mode = RSA_PKCS1_PADDING;
+ rctx->md_nid = NID_undef;
+ rctx->tbuf = NULL;
+
ctx->data = rctx;
+
+ return 1;
+ }
+
+static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
+ {
+ if (ctx->tbuf)
+ return 1;
+ ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
+ if (!ctx->tbuf)
+ return 0;
return 1;
}
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
- ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+
+ if (rctx->md_nid != NID_undef)
+ {
+
+ if (rctx->pad_mode == RSA_X931_PADDING)
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ memcpy(rctx->tbuf, tbs, tbslen);
+ rctx->tbuf[tbslen] = RSA_X931_hash_id(rctx->md_nid);
+ ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
+ sig, ctx->pkey->pkey.rsa,
+ RSA_X931_PADDING);
+ }
+ else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+ {
+ unsigned int sltmp;
+ ret = RSA_sign(rctx->md_nid, tbs, tbslen, sig, &sltmp,
+ ctx->pkey->pkey.rsa);
+ }
+ else
+ return -1;
+ }
+ else
+ ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
rctx->pad_mode);
if (ret < 0)
return ret;
{
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
- ret = RSA_public_decrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+
+ if (rctx->md_nid != NID_undef)
+ {
+ if (rctx->pad_mode == RSA_X931_PADDING)
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ ret = RSA_private_encrypt(tbslen, tbs,
+ rctx->tbuf, ctx->pkey->pkey.rsa,
+ RSA_X931_PADDING);
+ if (ret < 1)
+ return 0;
+ if (rctx->tbuf[ret] != RSA_X931_hash_id(rctx->md_nid))
+ {
+ RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+ RSA_R_ALGORITHM_MISMATCH);
+ return 0;
+ }
+ ret--;
+ memcpy(sig, rctx->tbuf, ret);
+ }
+ else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+ {
+ unsigned int sltmp;
+ ret = int_rsa_verify(rctx->md_nid, NULL, 0, sig, &sltmp,
+ tbs, tbslen, ctx->pkey->pkey.rsa);
+ }
+ else
+ return -1;
+ }
+ else
+ ret = RSA_public_decrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
rctx->pad_mode);
if (ret < 0)
return ret;
return 1;
}
+static int check_padding_nid(int nid, int padding)
+ {
+ if (nid == NID_undef)
+ return 1;
+ if (padding == RSA_NO_PADDING)
+ {
+ RSAerr(RSA_F_CHECK_PADDING_NID, RSA_R_INVALID_PADDING_MODE);
+ return 0;
+ }
+
+ if (padding == RSA_X931_PADDING)
+ {
+ if (RSA_X931_hash_id(nid) == -1)
+ {
+ RSAerr(RSA_F_CHECK_PADDING_NID,
+ RSA_R_INVALID_X931_DIGEST);
+ return 0;
+ }
+ return 1;
+ }
+
+ return 1;
+ }
+
+
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
RSA_PKEY_CTX *rctx = ctx->data;
switch (type)
{
-
case EVP_PKEY_CTRL_RSA_PADDING:
/* TODO: add PSS support */
if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_X931_PADDING))
{
if (ctx->operation == EVP_PKEY_OP_KEYGEN)
return -2;
+ if (!check_padding_nid(rctx->md_nid, p1))
+ return 0;
rctx->pad_mode = p1;
return 1;
}
return -2;
+ case EVP_PKEY_CTRL_MD_NID:
+ if (!check_padding_nid(p1, rctx->pad_mode))
+ return 0;
+ rctx->md_nid = p1;
+ return 1;
+
default:
return -2;
return(ret);
}
-int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
- unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *rm, unsigned int *prm_len,
+ unsigned char *sigbuf, unsigned int siglen,
+ RSA *rsa)
{
int i,ret=0,sigtype;
unsigned char *s;
return(0);
}
- if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+ if((dtype == NID_md5_sha1) && rm)
{
- return rsa->meth->rsa_verify(dtype, m, m_len,
- sigbuf, siglen, rsa);
+ i = RSA_public_decrypt((int)siglen,
+ sigbuf,rm,rsa,RSA_PKCS1_PADDING);
+ if (i <= 0)
+ return 0;
+ *prm_len = i;
+ return 1;
}
s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
goto err;
}
}
- if ( ((unsigned int)sig->digest->length != m_len) ||
+ if (rm)
+ {
+ memcpy(rm, sig->digest->data, sig->digest->length);
+ *prm_len = sig->digest->length;
+ ret = 1;
+ }
+ else if (((unsigned int)sig->digest->length != m_len) ||
(memcmp(m,sig->digest->data,m_len) != 0))
{
RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
return(ret);
}
+int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigbuf, unsigned int siglen,
+ RSA *rsa)
+ {
+
+ if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+ {
+ return rsa->meth->rsa_verify(dtype, m, m_len,
+ sigbuf, siglen, rsa);
+ }
+
+ return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
+ }