mirror of
https://github.com/openssl/openssl.git
synced 2024-11-24 18:43:34 +08:00
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
This commit is contained in:
parent
5d6383c83f
commit
216659eb87
10
CHANGES
10
CHANGES
@ -4,6 +4,16 @@
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -63,9 +63,11 @@
|
||||
#include <openssl/objects.h>
|
||||
#include "evp_locl.h"
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
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 */
|
||||
|
||||
@ -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,
|
||||
0, des_init_key, NULL,
|
||||
EVP_CIPH_RAND_KEY, des_init_key, NULL,
|
||||
EVP_CIPHER_set_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_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_get_asn1_iv,NULL)
|
||||
EVP_CIPHER_get_asn1_iv,des_ctrl)
|
||||
|
||||
static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
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);
|
||||
#endif
|
||||
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
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <openssl/objects.h>
|
||||
#include "evp_locl.h"
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv,int enc);
|
||||
@ -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,
|
||||
const unsigned char *iv,int enc);
|
||||
|
||||
static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DES_key_schedule ks1;/* key schedule */
|
||||
@ -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,
|
||||
0, des_ede_init_key, NULL,
|
||||
EVP_CIPH_RAND_KEY, des_ede_init_key, NULL,
|
||||
EVP_CIPHER_set_asn1_iv,
|
||||
EVP_CIPHER_get_asn1_iv,
|
||||
NULL)
|
||||
des3_ctrl)
|
||||
|
||||
#define des_ede3_cfb64_cipher des_ede_cfb64_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,
|
||||
#define des_ede3_ecb_cipher des_ede_ecb_cipher
|
||||
|
||||
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_get_asn1_iv,
|
||||
NULL)
|
||||
des3_ctrl)
|
||||
|
||||
BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,0,
|
||||
des_ede3_init_key,NULL,
|
||||
BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
|
||||
EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
|
||||
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,
|
||||
des_ede3_init_key,NULL,
|
||||
BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
|
||||
EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
|
||||
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,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
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[1],&data(ctx)->ks2);
|
||||
#endif
|
||||
memcpy(&data(ctx)->ks3,&data(ctx)->ks1,
|
||||
sizeof(data(ctx)->ks1));
|
||||
return 1;
|
||||
@ -214,13 +224,41 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
}
|
||||
#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[1],&data(ctx)->ks2);
|
||||
DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3);
|
||||
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
return &des_ede_ecb;
|
||||
|
@ -332,6 +332,8 @@ struct evp_cipher_st
|
||||
#define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80
|
||||
/* Don't use standard block padding */
|
||||
#define EVP_CIPH_NO_PADDING 0x100
|
||||
/* cipher handles random key generation */
|
||||
#define EVP_CIPH_RAND_KEY 0x200
|
||||
|
||||
/* ctrl() values */
|
||||
|
||||
@ -341,6 +343,7 @@ struct evp_cipher_st
|
||||
#define EVP_CTRL_SET_RC2_KEY_BITS 0x3
|
||||
#define EVP_CTRL_GET_RC5_ROUNDS 0x4
|
||||
#define EVP_CTRL_SET_RC5_ROUNDS 0x5
|
||||
#define EVP_CTRL_RAND_KEY 0x6
|
||||
|
||||
typedef struct evp_cipher_info_st
|
||||
{
|
||||
@ -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_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_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
|
||||
|
||||
#ifndef OPENSSL_NO_BIO
|
||||
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)
|
||||
}
|
||||
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
|
||||
}
|
||||
if ((npubk <= 0) || !pubk)
|
||||
return 1;
|
||||
if (RAND_bytes(key,EVP_MAX_KEY_LENGTH) <= 0)
|
||||
if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
|
||||
return 0;
|
||||
if (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)
|
||||
BIO_get_cipher_ctx(btmp, &ctx);
|
||||
keylen=EVP_CIPHER_key_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));
|
||||
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 (xalg->parameter == NULL)
|
||||
@ -440,7 +443,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
|
||||
evp_ctx=NULL;
|
||||
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)
|
||||
goto err;
|
||||
|
||||
@ -456,7 +460,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user