summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Salz <rsalz@akamai.com>2015-04-24 16:39:40 -0400
committerRich Salz <rsalz@openssl.org>2015-06-23 17:09:35 -0400
commit74924dcb3802640d7e2ae2e80ca6515d0a53de7a (patch)
tree6de4138b01d5f649bdaa32d858bd5fa20e9ad4b6
parentce7e647bc2c328404b1e3cdac6211773afdefe07 (diff)
More secure storage of key material.
Add secure heap for storage of private keys (when possible). Add BIO_s_secmem(), CBIGNUM, etc. Add BIO_CTX_secure_new so all BIGNUM's in the context are secure. Contributed by Akamai Technologies under the Corporate CLA. Reviewed-by: Richard Levitte <levitte@openssl.org>
-rw-r--r--CHANGES5
-rw-r--r--crypto/Makefile8
-rw-r--r--crypto/asn1/x_bignum.c32
-rw-r--r--crypto/bio/bss_mem.c36
-rw-r--r--crypto/bn/bn_ctx.c79
-rw-r--r--crypto/bn/bn_lib.c37
-rw-r--r--crypto/buffer/buffer.c42
-rw-r--r--crypto/dh/dh_ameth.c3
-rw-r--r--crypto/dh/dh_key.c2
-rw-r--r--crypto/dsa/dsa_ameth.c3
-rw-r--r--crypto/dsa/dsa_asn1.c2
-rw-r--r--crypto/dsa/dsa_key.c2
-rw-r--r--crypto/ec/ec_asn1.c2
-rw-r--r--crypto/mem.c73
-rw-r--r--crypto/rsa/rsa_asn1.c12
-rw-r--r--crypto/rsa/rsa_gen.c12
-rw-r--r--crypto/sec_mem.c513
-rw-r--r--doc/crypto/BIO_s_mem.pod7
-rw-r--r--doc/crypto/BN_CTX_new.pod15
-rw-r--r--doc/crypto/CRYPTO_secure_malloc.pod91
-rw-r--r--doc/crypto/bio.pod1
-rw-r--r--doc/crypto/bn.pod1
-rw-r--r--doc/crypto/buffer.pod14
-rw-r--r--include/openssl/bio.h1
-rw-r--r--include/openssl/bn.h3
-rw-r--r--include/openssl/buffer.h4
-rw-r--r--include/openssl/crypto.h23
-rw-r--r--test/Makefile14
-rw-r--r--test/secmemtest.c34
-rwxr-xr-xutil/libeay.num14
30 files changed, 1009 insertions, 76 deletions
diff --git a/CHANGES b/CHANGES
index fae11230fc..88b3d67273 100644
--- a/CHANGES
+++ b/CHANGES
@@ -126,6 +126,11 @@
NULL. Remove the non-null checks from callers. Save much code.
[Rich Salz]
+ *) Add secure heap for storage of private keys (when possible).
+ Add BIO_s_secmem(), CBIGNUM, etc.
+ Contributed by Akamai Technologies under our Corporate CLA.
+ [Rich Salz]
+
*) Experimental support for a new, fast, unbiased prime candidate generator,
bn_probable_prime_dh_coprime(). Not currently used by any prime generator.
[Felix Laurie von Massenbach <felix@erbridge.co.uk>]
diff --git a/crypto/Makefile b/crypto/Makefile
index 99cd65c5bc..b2cf528a91 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -36,10 +36,10 @@ LIB= $(TOP)/libcrypto.a
SHARED_LIB= libcrypto$(SHLIB_EXT)
LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
ebcdic.c uid.c o_time.c o_str.c o_dir.c thr_id.c lock.c fips_ers.c \
- o_init.c o_fips.c
+ o_init.c o_fips.c sec_mem.c
LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o \
ebcdic.o uid.o o_time.o o_str.o o_dir.o thr_id.o lock.o fips_ers.o \
- o_init.o o_fips.o $(CPUID_OBJ)
+ o_init.o o_fips.o sec_mem.o $(CPUID_OBJ)
SRC= $(LIBSRC)
@@ -208,6 +208,10 @@ o_time.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
o_time.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
o_time.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
o_time.o: ../include/openssl/stack.h ../include/openssl/symhacks.h o_time.c
+sec_mem.o: ../e_os.h ../include/openssl/crypto.h ../include/openssl/e_os2.h
+sec_mem.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+sec_mem.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+sec_mem.o: ../include/openssl/stack.h ../include/openssl/symhacks.h sec_mem.c
thr_id.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
thr_id.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
thr_id.o: ../include/openssl/err.h ../include/openssl/lhash.h
diff --git a/crypto/asn1/x_bignum.c b/crypto/asn1/x_bignum.c
index 8307a2d729..66ce000827 100644
--- a/crypto/asn1/x_bignum.c
+++ b/crypto/asn1/x_bignum.c
@@ -72,12 +72,15 @@
#define BN_SENSITIVE 1
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it);
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL, 0,
@@ -88,12 +91,21 @@ static ASN1_PRIMITIVE_FUNCS bignum_pf = {
bn_i2c
};
+static ASN1_PRIMITIVE_FUNCS cbignum_pf = {
+ NULL, 0,
+ bn_secure_new,
+ bn_free,
+ 0,
+ bn_secure_c2i,
+ bn_i2c
+};
+
ASN1_ITEM_start(BIGNUM)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
ASN1_ITEM_end(BIGNUM)
ASN1_ITEM_start(CBIGNUM)
- ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
+ ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM"
ASN1_ITEM_end(CBIGNUM)
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
@@ -105,6 +117,15 @@ static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
return 0;
}
+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ *pval = (ASN1_VALUE *)BN_secure_new();
+ if (*pval)
+ return 1;
+ else
+ return 0;
+}
+
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if (!*pval)
@@ -141,6 +162,7 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
BIGNUM *bn;
+
if (!*pval)
bn_new(pval, it);
bn = (BIGNUM *)*pval;
@@ -150,3 +172,11 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
}
return 1;
}
+
+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it)
+{
+ if (!*pval)
+ bn_secure_new(pval, it);
+ return bn_c2i(pval, cont, len, utype, free_cont, it);
+}
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index a1f5e8d960..485a8bf663 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -67,6 +67,7 @@ static int mem_puts(BIO *h, const char *str);
static int mem_gets(BIO *h, char *str, int size);
static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int mem_new(BIO *h);
+static int secmem_new(BIO *h);
static int mem_free(BIO *data);
static BIO_METHOD mem_method = {
BIO_TYPE_MEM,
@@ -80,6 +81,18 @@ static BIO_METHOD mem_method = {
mem_free,
NULL,
};
+static BIO_METHOD secmem_method = {
+ BIO_TYPE_MEM,
+ "secure memory buffer",
+ mem_write,
+ mem_read,
+ mem_puts,
+ mem_gets,
+ mem_ctrl,
+ secmem_new,
+ mem_free,
+ NULL,
+};
/*
* bio->num is used to hold the value to return on 'empty', if it is 0,
@@ -91,6 +104,11 @@ BIO_METHOD *BIO_s_mem(void)
return (&mem_method);
}
+BIO_METHOD *BIO_s_secmem(void)
+{
+ return(&secmem_method);
+}
+
BIO *BIO_new_mem_buf(void *buf, int len)
{
BIO *ret;
@@ -114,17 +132,27 @@ BIO *BIO_new_mem_buf(void *buf, int len)
return ret;
}
-static int mem_new(BIO *bi)
+static int mem_init(BIO *bi, unsigned long flags)
{
BUF_MEM *b;
- if ((b = BUF_MEM_new()) == NULL)
- return (0);
+ if ((b = BUF_MEM_new_ex(flags)) == NULL)
+ return(0);
bi->shutdown = 1;
bi->init = 1;
bi->num = -1;
bi->ptr = (char *)b;
- return (1);
+ return(1);
+}
+
+static int mem_new(BIO *bi)
+{
+ return (mem_init(bi, 0L));
+}
+
+static int secmem_new(BIO *bi)
+{
+ return (mem_init(bi, BUF_MEM_FLAG_SECURE));
}
static int mem_free(BIO *a)
diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c
index c023303b67..660e626a91 100644
--- a/crypto/bn/bn_ctx.c
+++ b/crypto/bn/bn_ctx.c
@@ -103,7 +103,7 @@ typedef struct bignum_pool {
} BN_POOL;
static void BN_POOL_init(BN_POOL *);
static void BN_POOL_finish(BN_POOL *);
-static BIGNUM *BN_POOL_get(BN_POOL *);
+static BIGNUM *BN_POOL_get(BN_POOL *, int);
static void BN_POOL_release(BN_POOL *, unsigned int);
/************/
@@ -138,6 +138,8 @@ struct bignum_ctx {
int err_stack;
/* Block "gets" until an "end" (compatibility behaviour) */
int too_many;
+ /* Flags. */
+ int flags;
};
/* Enable this to find BN_CTX bugs */
@@ -186,8 +188,9 @@ static void ctxdbg(BN_CTX *ctx)
BN_CTX *BN_CTX_new(void)
{
- BN_CTX *ret = OPENSSL_malloc(sizeof(*ret));
- if (!ret) {
+ BN_CTX *ret;
+
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -197,6 +200,16 @@ BN_CTX *BN_CTX_new(void)
ret->used = 0;
ret->err_stack = 0;
ret->too_many = 0;
+ ret->flags = 0;
+ return ret;
+}
+
+BN_CTX *BN_CTX_secure_new(void)
+{
+ BN_CTX *ret = BN_CTX_new();
+
+ if (ret)
+ ret->flags = BN_FLG_SECURE;
return ret;
}
@@ -258,10 +271,11 @@ void BN_CTX_end(BN_CTX *ctx)
BIGNUM *BN_CTX_get(BN_CTX *ctx)
{
BIGNUM *ret;
+
CTXDBG_ENTRY("BN_CTX_get", ctx);
if (ctx->err_stack || ctx->too_many)
return NULL;
- if ((ret = BN_POOL_get(&ctx->pool)) == NULL) {
+ if ((ret = BN_POOL_get(&ctx->pool, ctx->flags)) == NULL) {
/*
* Setting too_many prevents repeated "get" attempts from cluttering
* the error stack.
@@ -289,26 +303,23 @@ static void BN_STACK_init(BN_STACK *st)
static void BN_STACK_finish(BN_STACK *st)
{
- if (st->size)
- OPENSSL_free(st->indexes);
+ OPENSSL_free(st->indexes);
+ st->indexes = NULL;
}
static int BN_STACK_push(BN_STACK *st, unsigned int idx)
{
- if (st->depth == st->size)
+ if (st->depth == st->size) {
/* Need to expand */
- {
- unsigned int newsize = (st->size ?
- (st->size * 3 / 2) : BN_CTX_START_FRAMES);
- unsigned int *newitems = OPENSSL_malloc(newsize *
- sizeof(unsigned int));
- if (!newitems)
+ unsigned int newsize =
+ st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES;
+ unsigned int *newitems = OPENSSL_malloc(sizeof(*newitems) * newsize);
+ if (newitems == NULL)
return 0;
if (st->depth)
- memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int));
- if (st->size)
- OPENSSL_free(st->indexes);
+ memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth);
+ OPENSSL_free(st->indexes);
st->indexes = newitems;
st->size = newsize;
}
@@ -333,14 +344,13 @@ static void BN_POOL_init(BN_POOL *p)
static void BN_POOL_finish(BN_POOL *p)
{
+ unsigned int loop;
+ BIGNUM *bn;
+
while (p->head) {
- unsigned int loop = 0;
- BIGNUM *bn = p->head->vals;
- while (loop++ < BN_CTX_POOL_SIZE) {
+ for (loop = 0, bn = p->head->vals; loop++ < BN_CTX_POOL_SIZE; bn++)
if (bn->d)
BN_clear_free(bn);
- bn++;
- }
p->current = p->head->next;
OPENSSL_free(p->head);
p->head = p->current;
@@ -348,22 +358,25 @@ static void BN_POOL_finish(BN_POOL *p)
}
-static BIGNUM *BN_POOL_get(BN_POOL *p)
+static BIGNUM *BN_POOL_get(BN_POOL *p, int flag)
{
+ BIGNUM *bn;
+ unsigned int loop;
+
+ /* Full; allocate a new pool item and link it in. */
if (p->used == p->size) {
- BIGNUM *bn;
- unsigned int loop = 0;
BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(*item));
- if (!item)
+ if (item == NULL)
return NULL;
- /* Initialise the structure */
- bn = item->vals;
- while (loop++ < BN_CTX_POOL_SIZE)
- BN_init(bn++);
+ for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) {
+ BN_init(bn);
+ if ((flag & BN_FLG_SECURE) != 0)
+ BN_set_flags(bn, BN_FLG_SECURE);
+ }
item->prev = p->tail;
item->next = NULL;
- /* Link it in */
- if (!p->head)
+
+ if (p->head == NULL)
p->head = p->current = p->tail = item;
else {
p->tail->next = item;
@@ -375,6 +388,7 @@ static BIGNUM *BN_POOL_get(BN_POOL *p)
/* Return the first bignum from the new pool */
return item->vals;
}
+
if (!p->used)
p->current = p->head;
else if ((p->used % BN_CTX_POOL_SIZE) == 0)
@@ -385,10 +399,11 @@ static BIGNUM *BN_POOL_get(BN_POOL *p)
static void BN_POOL_release(BN_POOL *p, unsigned int num)
{
unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
+
p->used -= num;
while (num--) {
bn_check_top(p->current->vals + offset);
- if (!offset) {
+ if (offset == 0) {
offset = BN_CTX_POOL_SIZE - 1;
p->current = p->current->prev;
} else
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 4dabe26b10..b5f827a36c 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -232,8 +232,12 @@ void BN_clear_free(BIGNUM *a)
bn_check_top(a);
if (a->d != NULL) {
OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
- if (!(BN_get_flags(a, BN_FLG_STATIC_DATA)))
- OPENSSL_free(a->d);
+ if (!(BN_get_flags(a, BN_FLG_STATIC_DATA))) {
+ if (BN_get_flags(a,BN_FLG_SECURE))
+ OPENSSL_secure_free(a->d);
+ else
+ OPENSSL_free(a->d);
+ }
}
i = BN_get_flags(a, BN_FLG_MALLOCED);
OPENSSL_cleanse(a, sizeof(BIGNUM));
@@ -247,7 +251,12 @@ void BN_free(BIGNUM *a)
return;
bn_check_top(a);
if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
- OPENSSL_free(a->d);
+ if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) {
+ if (BN_get_flags(a, BN_FLG_SECURE))
+ OPENSSL_secure_free(a->d);
+ else
+ OPENSSL_free(a->d);
+ }
if (a->flags & BN_FLG_MALLOCED)
OPENSSL_free(a);
else {
@@ -281,6 +290,14 @@ BIGNUM *BN_new(void)
return (ret);
}
+ BIGNUM *BN_secure_new(void)
+ {
+ BIGNUM *ret = BN_new();
+ if (ret)
+ ret->flags |= BN_FLG_SECURE;
+ return (ret);
+ }
+
/* This is used both by bn_expand2() and bn_dup_expand() */
/* The caller MUST check that words > b->dmax before calling this */
static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
@@ -299,7 +316,10 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
return (NULL);
}
- a = A = OPENSSL_malloc(sizeof(*a) * words);
+ if (BN_get_flags(b,BN_FLG_SECURE))
+ a = A = OPENSSL_secure_malloc(words * sizeof(*a));
+ else
+ a = A = OPENSSL_malloc(words * sizeof(*a));
if (A == NULL) {
BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
return (NULL);
@@ -378,7 +398,12 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
BN_ULONG *a = bn_expand_internal(b, words);
if (!a)
return NULL;
- OPENSSL_free(b->d);
+ if (b->d) {
+ if (BN_get_flags(b,BN_FLG_SECURE))
+ OPENSSL_secure_free(b->d);
+ else
+ OPENSSL_free(b->d);
+ }
b->d = a;
b->dmax = words;
}
@@ -395,7 +420,7 @@ BIGNUM *BN_dup(const BIGNUM *a)
return NULL;
bn_check_top(a);
- t = BN_new();
+ t = BN_get_flags(a, BN_FLG_SECURE) ? BN_secure_new() : BN_new();
if (t == NULL)
return NULL;
if (!BN_copy(t, a)) {
diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c
index 2beacce6d7..5ee11f4c70 100644
--- a/crypto/buffer/buffer.c
+++ b/crypto/buffer/buffer.c
@@ -67,6 +67,16 @@
*/
#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
+BUF_MEM *BUF_MEM_new_ex(unsigned long flags)
+{
+ BUF_MEM *ret;
+
+ ret = BUF_MEM_new();
+ if (ret != NULL)
+ ret->flags = flags;
+ return (ret);
+}
+
BUF_MEM *BUF_MEM_new(void)
{
BUF_MEM *ret;
@@ -76,6 +86,7 @@ BUF_MEM *BUF_MEM_new(void)
BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE);
return (NULL);
}
+ ret->flags = 0;
ret->length = 0;
ret->max = 0;
ret->data = NULL;
@@ -88,11 +99,30 @@ void BUF_MEM_free(BUF_MEM *a)
return;
if (a->data != NULL) {
- OPENSSL_clear_free(a->data, a->max);
+ memset(a->data, 0, (unsigned int)a->max);
+ if (a->flags & BUF_MEM_FLAG_SECURE)
+ OPENSSL_secure_free(a->data);
+ else
+ OPENSSL_clear_free(a->data, a->max);
}
OPENSSL_free(a);
}
+/* Allocate a block of secure memory; copy over old data if there
+ * was any, and then free it. */
+static char *sec_alloc_realloc(BUF_MEM *str, size_t len)
+{
+ char *ret;
+
+ ret = OPENSSL_secure_malloc(len);
+ if (str->data != NULL) {
+ if (ret != NULL)
+ memcpy(ret, str->data, str->length);
+ OPENSSL_secure_free(str->data);
+ }
+ return (ret);
+}
+
size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
{
char *ret;
@@ -113,7 +143,10 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
return 0;
}
n = (len + 3) / 3 * 4;
- ret = OPENSSL_realloc(str->data, n);
+ if ((str->flags & BUF_MEM_FLAG_SECURE))
+ ret = sec_alloc_realloc(str, n);
+ else
+ ret = OPENSSL_realloc(str->data, n);
if (ret == NULL) {
BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
len = 0;
@@ -147,7 +180,10 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
return 0;
}
n = (len + 3) / 3 * 4;
- ret = OPENSSL_realloc_clean(str->data, str->max, n);
+ if ((str->flags & BUF_MEM_FLAG_SECURE))
+ ret = sec_alloc_realloc(str, n);
+ else
+ ret = OPENSSL_realloc_clean(str->data, str->max, n);
if (ret == NULL) {
BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
len = 0;
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 98f8570a2f..efb3d805e8 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -228,7 +228,8 @@ static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
goto decerr;
/* We have parameters now set private key */
- if ((dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)) == NULL) {
+ if ((dh->priv_key = BN_secure_new()) == NULL
+ || !ASN1_INTEGER_to_BN(privkey, dh->priv_key)) {
DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
goto dherr;
}
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index ff91d41d79..b6c3038976 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -125,7 +125,7 @@ static int generate_key(DH *dh)
goto err;
if (dh->priv_key == NULL) {
- priv_key = BN_new();
+ priv_key = BN_secure_new();
if (priv_key == NULL)
goto err;
generate_new_key = 1;
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index 01b3497552..73dd158cee 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -245,7 +245,8 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL)
goto decerr;
/* We have parameters now set private key */
- if ((dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)) == NULL) {
+ if ((dsa->priv_key = BN_secure_new()) == NULL
+ || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) {
DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
goto dsaerr;
}
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index bb2434e20e..85db147822 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -113,7 +113,7 @@ ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
ASN1_SIMPLE(DSA, q, BIGNUM),
ASN1_SIMPLE(DSA, g, BIGNUM),
ASN1_SIMPLE(DSA, pub_key, BIGNUM),
- ASN1_SIMPLE(DSA, priv_key, BIGNUM)
+ ASN1_SIMPLE(DSA, priv_key, CBIGNUM)
} ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index 01a83e0018..19d21eacf7 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -82,7 +82,7 @@ static int dsa_builtin_keygen(DSA *dsa)
goto err;
if (dsa->priv_key == NULL) {
- if ((priv_key = BN_new()) == NULL)
+ if ((priv_key = BN_secure_new()) == NULL)
goto err;
} else
priv_key = dsa->priv_key;
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index ebafc10de7..3f971aa46c 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -1023,6 +1023,8 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
ret->version = priv_key->version;
if (priv_key->privateKey) {
+ if (ret->priv_key == NULL)
+ ret->priv_key = BN_secure_new();
ret->priv_key = BN_bin2bn(ASN1_STRING_data(priv_key->privateKey),
ASN1_STRING_length(priv_key->privateKey),
ret->priv_key);
diff --git a/crypto/mem.c b/crypto/mem.c
index b98e44fc5a..56c3585865 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -94,6 +94,15 @@ static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
static void (*free_func) (void *) = free;
+static void *(*malloc_secure_func)(size_t) = malloc;
+static void *default_malloc_secure_ex(size_t num, const char *file, int line)
+{
+ return malloc_secure_func(num);
+}
+static void *(*malloc_secure_ex_func)(size_t, const char *file, int line)
+ = default_malloc_secure_ex;
+static void (*free_secure_func)(void *) = free;
+
static void *(*malloc_locked_func) (size_t) = malloc;
static void *default_malloc_locked_ex(size_t num, const char *file, int line)
{
@@ -145,6 +154,11 @@ int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
realloc_func = r;
realloc_ex_func = default_realloc_ex;
free_func = f;
+ /* If user wants to intercept the secure or locked functions, do it
+ * after the basic functions. */
+ malloc_secure_func = m;
+ malloc_secure_ex_func = default_malloc_secure_ex;
+ free_secure_func = f;
malloc_locked_func = m;
malloc_locked_ex_func = default_malloc_locked_ex;
free_locked_func = f;
@@ -164,6 +178,44 @@ int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
realloc_func = 0;
realloc_ex_func = r;
free_func = f;
+ malloc_secure_func = 0;
+ malloc_secure_ex_func = m;
+ free_secure_func = f;
+ malloc_locked_func = 0;
+ malloc_locked_ex_func = m;
+ free_locked_func = f;
+ return 1;
+}
+
+int CRYPTO_set_secure_mem_functions(void *(*m)(size_t), void (*f)(void *))
+{
+ /* Dummy call just to ensure OPENSSL_init() gets linked in */
+ OPENSSL_init();
+ if (!allow_customize)
+ return 0;
+ if ((m == 0) || (f == 0))
+ return 0;
+ malloc_secure_func = m;
+ malloc_secure_ex_func = default_malloc_secure_ex;
+ free_secure_func = f;
+ /* If user wants to intercept the locked functions, do it after
+ * the secure functions. */
+ malloc_locked_func = m;
+ malloc_locked_ex_func = default_malloc_secure_ex;
+ free_locked_func = f;
+ return 1;
+}
+
+int CRYPTO_set_secure_mem_ex_functions(void *(*m)(size_t, const char *, int),
+ void (*f)(void *))
+{
+ if (!allow_customize)
+ return 0;
+ if ((m == NULL) || (f == NULL))
+ return 0;
+ malloc_secure_func = 0;
+ malloc_secure_ex_func = m;
+ free_secure_func = f;
malloc_locked_func = 0;
malloc_locked_ex_func = m;
free_locked_func = f;
@@ -191,7 +243,7 @@ int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
return 0;
malloc_locked_func = 0;
malloc_locked_ex_func = m;
- free_func = f;
+ free_locked_func = f;
return 1;
}
@@ -236,6 +288,25 @@ void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
*f = free_func;
}
+void CRYPTO_get_secure_mem_functions(void *(**m)(size_t), void (**f)(void *))
+{
+ if (m != NULL)
+ *m = (malloc_secure_ex_func == default_malloc_secure_ex) ?
+ malloc_secure_func : 0;
+ if (f != NULL)
+ *f=free_secure_func;
+ }
+
+void CRYPTO_get_secure_mem_ex_functions(void *(**m)(size_t,const char *,int),
+ void (**f)(void *))
+{
+ if (m != NULL)
+ *m = (malloc_secure_ex_func != default_malloc_secure_ex) ?
+ malloc_secure_ex_func : 0;
+ if (f != NULL)
+ *f=free_secure_func;
+}
+
void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
void (**f) (void *))
{
diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c
index 0cf1b2ab94..8061aed5a9 100644
--- a/crypto/rsa/rsa_asn1.c
+++ b/crypto/rsa/rsa_asn1.c
@@ -85,12 +85,12 @@ ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
ASN1_SIMPLE(RSA, version, LONG),
ASN1_SIMPLE(RSA, n, BIGNUM),
ASN1_SIMPLE(RSA, e, BIGNUM),
- ASN1_SIMPLE(RSA, d, BIGNUM),
- ASN1_SIMPLE(RSA, p, BIGNUM),
- ASN1_SIMPLE(RSA, q, BIGNUM),
- ASN1_SIMPLE(RSA, dmp1, BIGNUM),
- ASN1_SIMPLE(RSA, dmq1, BIGNUM),
- ASN1_SIMPLE(RSA, iqmp, BIGNUM)
+ ASN1_SIMPLE(RSA, d, CBIGNUM),
+ ASN1_SIMPLE(RSA, p, CBIGNUM),
+ ASN1_SIMPLE(RSA, q, CBIGNUM),
+ ASN1_SIMPLE(RSA, dmp1, CBIGNUM),
+ ASN1_SIMPLE(RSA, dmq1, CBIGNUM),
+ ASN1_SIMPLE(RSA, iqmp, CBIGNUM)
} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index e81be75e44..e40186aced 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -117,19 +117,19 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
/* We need the RSA components non-NULL */
if (!rsa->n && ((rsa->n = BN_new()) == NULL))
goto err;
- if (!rsa->d && ((rsa->d = BN_new()) == NULL))