提交 216659eb 编写于 作者: D Dr. Stephen Henson

Enhance EVP code to generate random symmetric keys of the

appropriate form, for example correct DES parity.

Update S/MIME code and EVP_SealInit to use new functions.

PR: 700
上级 5d6383c8
...@@ -4,6 +4,16 @@ ...@@ -4,6 +4,16 @@
Changes between 0.9.7c and 0.9.8 [xx XXX xxxx] Changes between 0.9.7c and 0.9.8 [xx XXX xxxx]
*) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality.
This will generate a random key of the appropriate length based on the
cipher context. The EVP_CIPHER can provide its own random key generation
routine to support keys of a specific form. This is used in the des and
3des routines to generate a key of the correct parity. Update S/MIME
code to use new functions and hence generate correct parity DES keys.
Add EVP_CHECK_DES_KEY #define to return an error if the key is not
valid (weak or incorrect parity).
[Steve Henson]
*) Add a local set of CRLs that can be used by X509_verify_cert() as well *) Add a local set of CRLs that can be used by X509_verify_cert() as well
as looking them up. This is useful when the verified structure may contain as looking them up. This is useful when the verified structure may contain
CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs
......
...@@ -63,9 +63,11 @@ ...@@ -63,9 +63,11 @@
#include <openssl/objects.h> #include <openssl/objects.h>
#include "evp_locl.h" #include "evp_locl.h"
#include <openssl/des.h> #include <openssl/des.h>
#include <openssl/rand.h>
static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc); const unsigned char *iv, int enc);
static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */ /* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */
...@@ -127,26 +129,48 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ...@@ -127,26 +129,48 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
} }
BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
0, des_init_key, NULL, EVP_CIPH_RAND_KEY, des_init_key, NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv, EVP_CIPHER_get_asn1_iv,
NULL) des_ctrl)
BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,0,des_init_key,NULL, BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,
EVP_CIPH_RAND_KEY, des_init_key,NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,NULL) EVP_CIPHER_get_asn1_iv,des_ctrl)
BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,0,des_init_key,NULL, BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,
EVP_CIPH_RAND_KEY,des_init_key,NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,NULL) EVP_CIPHER_get_asn1_iv,des_ctrl)
static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc) const unsigned char *iv, int enc)
{ {
DES_cblock *deskey = (DES_cblock *)key; DES_cblock *deskey = (DES_cblock *)key;
#ifdef EVP_CHECK_DES_KEY
if(DES_set_key_checked(deskey,ctx->cipher_data) != 0)
return 0;
#else
DES_set_key_unchecked(deskey,ctx->cipher_data); DES_set_key_unchecked(deskey,ctx->cipher_data);
#endif
return 1; return 1;
} }
static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
switch(type)
{
case EVP_CTRL_RAND_KEY:
if (RAND_bytes(ptr, 8) <= 0)
return 0;
DES_set_odd_parity((DES_cblock *)ptr);
return 1;
default:
return -1;
}
}
#endif #endif
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <openssl/objects.h> #include <openssl/objects.h>
#include "evp_locl.h" #include "evp_locl.h"
#include <openssl/des.h> #include <openssl/des.h>
#include <openssl/rand.h>
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc); const unsigned char *iv,int enc);
...@@ -70,6 +71,8 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ...@@ -70,6 +71,8 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc); const unsigned char *iv,int enc);
static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
typedef struct typedef struct
{ {
DES_key_schedule ks1;/* key schedule */ DES_key_schedule ks1;/* key schedule */
...@@ -161,10 +164,10 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ...@@ -161,10 +164,10 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
} }
BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
0, des_ede_init_key, NULL, EVP_CIPH_RAND_KEY, des_ede_init_key, NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv, EVP_CIPHER_get_asn1_iv,
NULL) des3_ctrl)
#define des_ede3_cfb64_cipher des_ede_cfb64_cipher #define des_ede3_cfb64_cipher des_ede_cfb64_cipher
#define des_ede3_ofb_cipher des_ede_ofb_cipher #define des_ede3_ofb_cipher des_ede_ofb_cipher
...@@ -172,28 +175,35 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, ...@@ -172,28 +175,35 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
#define des_ede3_ecb_cipher des_ede_ecb_cipher #define des_ede3_ecb_cipher des_ede_ecb_cipher
BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
0, des_ede3_init_key, NULL, EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv, EVP_CIPHER_get_asn1_iv,
NULL) des3_ctrl)
BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,0, BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
des_ede3_init_key,NULL, EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,NULL) EVP_CIPHER_get_asn1_iv,
des3_ctrl)
BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,0, BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
des_ede3_init_key,NULL, EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,NULL) EVP_CIPHER_get_asn1_iv,
des3_ctrl)
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc) const unsigned char *iv, int enc)
{ {
DES_cblock *deskey = (DES_cblock *)key; DES_cblock *deskey = (DES_cblock *)key;
#ifdef EVP_CHECK_DES_KEY
if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1)
!! DES_set_key_checked(&deskey[1],&data(ctx)->ks2))
return 0;
#else
DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1); DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2); DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
#endif
memcpy(&data(ctx)->ks3,&data(ctx)->ks1, memcpy(&data(ctx)->ks3,&data(ctx)->ks1,
sizeof(data(ctx)->ks1)); sizeof(data(ctx)->ks1));
return 1; return 1;
...@@ -214,13 +224,41 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ...@@ -214,13 +224,41 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
} }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
#ifdef EVP_CHECK_DES_KEY
if (DES_set_key_checked(&deskey[0],&data(ctx)->ks1)
|| DES_set_key_checked(&deskey[1],&data(ctx)->ks2)
|| DES_set_key_checked(&deskey[2],&data(ctx)->ks3))
return 0;
#else
DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1); DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2); DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3); DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3);
#endif
return 1; return 1;
} }
static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
DES_cblock *deskey = ptr;
switch(type)
{
case EVP_CTRL_RAND_KEY:
if (RAND_bytes(ptr, c->key_len) <= 0)
return 0;
DES_set_odd_parity(deskey);
if (c->key_len >= 16)
DES_set_odd_parity(deskey + 1);
if (c->key_len >= 24)
DES_set_odd_parity(deskey + 2);
return 1;
default:
return -1;
}
}
const EVP_CIPHER *EVP_des_ede(void) const EVP_CIPHER *EVP_des_ede(void)
{ {
return &des_ede_ecb; return &des_ede_ecb;
......
...@@ -332,6 +332,8 @@ struct evp_cipher_st ...@@ -332,6 +332,8 @@ struct evp_cipher_st
#define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 #define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80
/* Don't use standard block padding */ /* Don't use standard block padding */
#define EVP_CIPH_NO_PADDING 0x100 #define EVP_CIPH_NO_PADDING 0x100
/* cipher handles random key generation */
#define EVP_CIPH_RAND_KEY 0x200
/* ctrl() values */ /* ctrl() values */
...@@ -341,6 +343,7 @@ struct evp_cipher_st ...@@ -341,6 +343,7 @@ struct evp_cipher_st
#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 #define EVP_CTRL_SET_RC2_KEY_BITS 0x3
#define EVP_CTRL_GET_RC5_ROUNDS 0x4 #define EVP_CTRL_GET_RC5_ROUNDS 0x4
#define EVP_CTRL_SET_RC5_ROUNDS 0x5 #define EVP_CTRL_SET_RC5_ROUNDS 0x5
#define EVP_CTRL_RAND_KEY 0x6
typedef struct evp_cipher_info_st typedef struct evp_cipher_info_st
{ {
...@@ -567,6 +570,7 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); ...@@ -567,6 +570,7 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
#ifndef OPENSSL_NO_BIO #ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_md(void); BIO_METHOD *BIO_f_md(void);
......
...@@ -534,3 +534,13 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) ...@@ -534,3 +534,13 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
} }
return ret; return ret;
} }
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
{
if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
if (RAND_bytes(key, ctx->key_len) <= 0)
return 0;
return 1;
}
...@@ -78,7 +78,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek ...@@ -78,7 +78,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek
} }
if ((npubk <= 0) || !pubk) if ((npubk <= 0) || !pubk)
return 1; return 1;
if (RAND_bytes(key,EVP_MAX_KEY_LENGTH) <= 0) if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
return 0; return 0;
if (EVP_CIPHER_CTX_iv_length(ctx)) if (EVP_CIPHER_CTX_iv_length(ctx))
RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx)); RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx));
......
...@@ -215,11 +215,14 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) ...@@ -215,11 +215,14 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
BIO_get_cipher_ctx(btmp, &ctx); BIO_get_cipher_ctx(btmp, &ctx);
keylen=EVP_CIPHER_key_length(evp_cipher); keylen=EVP_CIPHER_key_length(evp_cipher);
ivlen=EVP_CIPHER_iv_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher);
if (RAND_bytes(key,keylen) <= 0)
goto err;
xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1); if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
goto err;
if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
goto err;
if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
goto err;
if (ivlen > 0) { if (ivlen > 0) {
if (xalg->parameter == NULL) if (xalg->parameter == NULL)
...@@ -440,7 +443,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) ...@@ -440,7 +443,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
evp_ctx=NULL; evp_ctx=NULL;
BIO_get_cipher_ctx(etmp,&evp_ctx); BIO_get_cipher_ctx(etmp,&evp_ctx);
EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0); if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
goto err;
if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
goto err; goto err;
...@@ -456,7 +460,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) ...@@ -456,7 +460,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
goto err; goto err;
} }
} }
EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0); if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
goto err;
OPENSSL_cleanse(tmp,jj); OPENSSL_cleanse(tmp,jj);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册