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]
|
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 @@
|
|||||||
#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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@
|
|||||||
#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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
#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,
|
|||||||
}
|
}
|
||||||
#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
|
|||||||
#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
|
|||||||
#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);
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user