summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2015-03-13 16:48:01 +0000
committerMatt Caswell <matt@openssl.org>2015-03-25 12:33:37 +0000
commit8817e2e0c998757d3bd036d7f45fe8d0a49fbe2d (patch)
tree463a2d7d0c4681a8784083ee2b9cfe3446474e29
parent7b611e5fe8eaac9512f72094c460f3ed6040076a (diff)
Fix return checks in GOST engine
Filled in lots of return value checks that were missing the GOST engine, and added appropriate error handling. Reviewed-by: Richard Levitte <levitte@openssl.org>
-rw-r--r--engines/ccgost/e_gost_err.c3
-rw-r--r--engines/ccgost/e_gost_err.h1
-rw-r--r--engines/ccgost/gost2001.c229
-rw-r--r--engines/ccgost/gost_ameth.c36
-rw-r--r--engines/ccgost/gost_pmeth.c2
-rw-r--r--engines/ccgost/gost_sign.c79
6 files changed, 279 insertions, 71 deletions
diff --git a/engines/ccgost/e_gost_err.c b/engines/ccgost/e_gost_err.c
index 47022b1259..0afd91311d 100644
--- a/engines/ccgost/e_gost_err.c
+++ b/engines/ccgost/e_gost_err.c
@@ -1,6 +1,6 @@
/* e_gost_err.c */
/* ====================================================================
- * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -90,6 +90,7 @@ static ERR_STRING_DATA GOST_str_functs[] = {
{ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"},
{ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"},
{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"},
+ {ERR_FUNC(GOST_F_GOST_SIGN_KEYGEN), "GOST_SIGN_KEYGEN"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"},
diff --git a/engines/ccgost/e_gost_err.h b/engines/ccgost/e_gost_err.h
index e55ebf8b34..b18395718f 100644
--- a/engines/ccgost/e_gost_err.h
+++ b/engines/ccgost/e_gost_err.h
@@ -90,6 +90,7 @@ void ERR_GOST_error(int function, int reason, char *file, int line);
# define GOST_F_GOST_IMIT_CTRL 114
# define GOST_F_GOST_IMIT_FINAL 140
# define GOST_F_GOST_IMIT_UPDATE 115
+# define GOST_F_GOST_SIGN_KEYGEN 142
# define GOST_F_PARAM_COPY_GOST01 116
# define GOST_F_PARAM_COPY_GOST94 117
# define GOST_F_PKEY_GOST01CP_DECRYPT 118
diff --git a/engines/ccgost/gost2001.c b/engines/ccgost/gost2001.c
index b3eec8a19f..5c4efd6e57 100644
--- a/engines/ccgost/gost2001.c
+++ b/engines/ccgost/gost2001.c
@@ -41,6 +41,11 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
BN_CTX *ctx = BN_CTX_new();
int ok = 0;
+ if(!ctx) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
BN_CTX_start(ctx);
p = BN_CTX_get(ctx);
a = BN_CTX_get(ctx);
@@ -48,6 +53,10 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
q = BN_CTX_get(ctx);
+ if(!p || !a || !b || !x || !y || !q) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
while (params->nid != NID_undef && params->nid != nid)
params++;
if (params->nid == NID_undef) {
@@ -55,18 +64,33 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
GOST_R_UNSUPPORTED_PARAMETER_SET);
goto err;
}
- BN_hex2bn(&p, params->p);
- BN_hex2bn(&a, params->a);
- BN_hex2bn(&b, params->b);
+ if(!BN_hex2bn(&p, params->p)
+ || !BN_hex2bn(&a, params->a)
+ || !BN_hex2bn(&b, params->b)) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
grp = EC_GROUP_new_curve_GFp(p, a, b, ctx);
+ if(!grp) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
P = EC_POINT_new(grp);
+ if(!P) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- BN_hex2bn(&x, params->x);
- BN_hex2bn(&y, params->y);
- EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx);
- BN_hex2bn(&q, params->q);
+ if(!BN_hex2bn(&x, params->x)
+ || !BN_hex2bn(&y, params->y)
+ || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx)
+ || !BN_hex2bn(&q, params->q)) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
#ifdef DEBUG_KEYS
fprintf(stderr, "Set params index %d oid %s\nq=",
(params - R3410_2001_paramset), OBJ_nid2sn(params->nid));
@@ -74,16 +98,23 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
fprintf(stderr, "\n");
#endif
- EC_GROUP_set_generator(grp, P, q, NULL);
+ if(!EC_GROUP_set_generator(grp, P, q, NULL)) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
EC_GROUP_set_curve_name(grp, params->nid);
-
- EC_KEY_set_group(eckey, grp);
+ if(!EC_KEY_set_group(eckey, grp)) {
+ GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
ok = 1;
err:
- EC_POINT_free(P);
- EC_GROUP_free(grp);
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
+ if (P) EC_POINT_free(P);
+ if (grp) EC_GROUP_free(grp);
+ if (ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
return ok;
}
@@ -94,7 +125,7 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
*/
DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
- DSA_SIG *newsig = NULL;
+ DSA_SIG *newsig = NULL, *ret = NULL;
BIGNUM *md = hashsum2bn(dgst);
BIGNUM *order = NULL;
const EC_GROUP *group;
@@ -103,6 +134,10 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
NULL, *e = NULL;
EC_POINT *C = NULL;
BN_CTX *ctx = BN_CTX_new();
+ if(!ctx || !md) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
BN_CTX_start(ctx);
OPENSSL_assert(dlen == 32);
newsig = DSA_SIG_new();
@@ -111,11 +146,25 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
goto err;
}
group = EC_KEY_get0_group(eckey);
+ if(!group) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
order = BN_CTX_get(ctx);
- EC_GROUP_get_order(group, order, ctx);
+ if(!order || !EC_GROUP_get_order(group, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
priv_key = EC_KEY_get0_private_key(eckey);
+ if(!priv_key) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
e = BN_CTX_get(ctx);
- BN_mod(e, md, order, ctx);
+ if(!e || !BN_mod(e, md, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
#ifdef DEBUG_SIGN
fprintf(stderr, "digest as bignum=");
BN_print_fp(stderr, md);
@@ -128,55 +177,80 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
}
k = BN_CTX_get(ctx);
C = EC_POINT_new(group);
+ if(!k || !C) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
do {
do {
if (!BN_rand_range(k, order)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN,
GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
- DSA_SIG_free(newsig);
- newsig = NULL;
goto err;
}
if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
- DSA_SIG_free(newsig);
- newsig = NULL;
goto err;
}
if (!X)
X = BN_CTX_get(ctx);
+ if (!r)
+ r = BN_CTX_get(ctx);
+ if (!X || !r) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
- DSA_SIG_free(newsig);
- newsig = NULL;
goto err;
}
- if (!r)
- r = BN_CTX_get(ctx);
- BN_nnmod(r, X, order, ctx);
+
+ if(!BN_nnmod(r, X, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
}
while (BN_is_zero(r));
/* s = (r*priv_key+k*e) mod order */
if (!tmp)
tmp = BN_CTX_get(ctx);
- BN_mod_mul(tmp, priv_key, r, order, ctx);
if (!tmp2)
tmp2 = BN_CTX_get(ctx);
- BN_mod_mul(tmp2, k, e, order, ctx);
if (!s)
s = BN_CTX_get(ctx);
- BN_mod_add(s, tmp, tmp2, order, ctx);
+ if (!tmp || !tmp2 || !s) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if(!BN_mod_mul(tmp, priv_key, r, order, ctx)
+ || !BN_mod_mul(tmp2, k, e, order, ctx)
+ || !BN_mod_add(s, tmp, tmp2, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
}
while (BN_is_zero(s));
newsig->s = BN_dup(s);
newsig->r = BN_dup(r);
+ if(!newsig->s || !newsig->r) {
+ GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ret = newsig;
err:
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- EC_POINT_free(C);
- BN_free(md);
- return newsig;
+ if(ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (C) EC_POINT_free(C);
+ if (md) BN_free(md);
+ if (!ret && newsig) {
+ DSA_SIG_free(newsig);
+ }
+ return ret;
}
/*
@@ -196,6 +270,11 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
const EC_POINT *pub_key = NULL;
int ok = 0;
+ if(!ctx || !group) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
e = BN_CTX_get(ctx);
@@ -205,9 +284,17 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
X = BN_CTX_get(ctx);
R = BN_CTX_get(ctx);
v = BN_CTX_get(ctx);
+ if(!order || !e || !z1 || !z2 || !tmp || !X || !R || !v) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- EC_GROUP_get_order(group, order, ctx);
pub_key = EC_KEY_get0_public_key(ec);
+ if(!pub_key || !EC_GROUP_get_order(group, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
(BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY,
@@ -217,19 +304,28 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
}
md = hashsum2bn(dgst);
- BN_mod(e, md, order, ctx);
+ if(!md || !BN_mod(e, md, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
#ifdef DEBUG_SIGN
fprintf(stderr, "digest as bignum: ");
BN_print_fp(stderr, md);
fprintf(stderr, "\ndigest mod q: ");
BN_print_fp(stderr, e);
#endif
- if (BN_is_zero(e))
- BN_one(e);
+ if (BN_is_zero(e) && !BN_one(e)) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
v = BN_mod_inverse(v, e, order, ctx);
- BN_mod_mul(z1, sig->s, v, order, ctx);
- BN_sub(tmp, order, sig->r);
- BN_mod_mul(z2, tmp, v, order, ctx);
+ if(!v
+ || !BN_mod_mul(z1, sig->s, v, order, ctx)
+ || !BN_sub(tmp, order, sig->r)
+ || !BN_mod_mul(z2, tmp, v, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
#ifdef DEBUG_SIGN
fprintf(stderr, "\nInverted digest value: ");
BN_print_fp(stderr, v);
@@ -239,6 +335,10 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
BN_print_fp(stderr, z2);
#endif
C = EC_POINT_new(group);
+ if (!C) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
goto err;
@@ -247,7 +347,10 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
- BN_mod(R, X, order, ctx);
+ if(!BN_mod(R, X, order, ctx)) {
+ GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
#ifdef DEBUG_SIGN
fprintf(stderr, "\nX=");
BN_print_fp(stderr, X);
@@ -261,10 +364,12 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
ok = 1;
}
err:
- EC_POINT_free(C);
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- BN_free(md);
+ if (C) EC_POINT_free(C);
+ if (ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (md) BN_free(md);
return ok;
}
@@ -287,6 +392,10 @@ int gost2001_compute_public(EC_KEY *ec)
return 0;
}
ctx = BN_CTX_new();
+ if(!ctx) {
+ GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
BN_CTX_start(ctx);
if (!(priv_key = EC_KEY_get0_private_key(ec))) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
@@ -294,6 +403,10 @@ int gost2001_compute_public(EC_KEY *ec)
}
pub_key = EC_POINT_new(group);
+ if(!pub_key) {
+ GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
goto err;
@@ -304,9 +417,11 @@ int gost2001_compute_public(EC_KEY *ec)
}
ok = 256;
err:
- BN_CTX_end(ctx);
- EC_POINT_free(pub_key);
- BN_CTX_free(ctx);
+ if (pub_key) EC_POINT_free(pub_key);
+ if (ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
return ok;
}
@@ -320,7 +435,13 @@ int gost2001_keygen(EC_KEY *ec)
{
BIGNUM *order = BN_new(), *d = BN_new();
const EC_GROUP *group = EC_KEY_get0_group(ec);
- EC_GROUP_get_order(group, order, NULL);
+
+ if(!group || !EC_GROUP_get_order(group, order, NULL)) {
+ GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
+ BN_free(d);
+ BN_free(order);
+ return 0;
+ }
do {
if (!BN_rand_range(d, order)) {
@@ -332,7 +453,13 @@ int gost2001_keygen(EC_KEY *ec)
}
}
while (BN_is_zero(d));
- EC_KEY_set_private_key(ec, d);
+
+ if(!EC_KEY_set_private_key(ec, d)) {
+ GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
+ BN_free(d);
+ BN_free(order);
+ return 0;
+ }
BN_free(d);
BN_free(order);
return gost2001_compute_public(ec);
diff --git a/engines/ccgost/gost_ameth.c b/engines/ccgost/gost_ameth.c
index a5d80a10a8..bc4532558c 100644
--- a/engines/ccgost/gost_ameth.c
+++ b/engines/ccgost/gost_ameth.c
@@ -115,7 +115,10 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
}
param_nid = OBJ_obj2nid(gkp->key_params);
GOST_KEY_PARAMS_free(gkp);
- EVP_PKEY_set_type(pkey, pkey_nid);
+ if(!EVP_PKEY_set_type(pkey, pkey_nid)) {
+ GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
switch (pkey_nid) {
case NID_id_GostR3410_94:
{
@@ -548,9 +551,19 @@ static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
}
if (!eto) {
eto = EC_KEY_new();
- EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto);
+ if(!eto) {
+ GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) {
+ GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+ if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) {
+ GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR);
+ return 0;
}
- EC_KEY_set_group(eto, EC_KEY_get0_group(efrom));
if (EC_KEY_get0_private_key(eto)) {
gost2001_compute_public(eto);
}
@@ -745,8 +758,21 @@ static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
}
X = BN_new();
Y = BN_new();
- EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
- pub_key, X, Y, NULL);
+ if(!X || !Y) {
+ GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
+ if(X) BN_free(X);
+ if(Y) BN_free(Y);
+ BN_free(order);
+ return 0;
+ }
+ if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
+ pub_key, X, Y, NULL)) {
+ GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR);
+ BN_free(X);
+ BN_free(Y);
+ BN_free(order);
+ return 0;
+ }
data_len = 2 * BN_num_bytes(order);
BN_free(order);
databuf = OPENSSL_malloc(data_len);
diff --git a/engines/ccgost/gost_pmeth.c b/engines/ccgost/gost_pmeth.c
index f1220e8ccd..673b5387ae 100644
--- a/engines/ccgost/gost_pmeth.c
+++ b/engines/ccgost/gost_pmeth.c
@@ -509,7 +509,7 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
long keylen;
int ret;
unsigned char *keybuf = string_to_hex(value, &keylen);
- if (keylen != 32) {
+ if (!keybuf || keylen != 32) {
GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
GOST_R_INVALID_MAC_KEY_LENGTH);
OPENSSL_free(keybuf);
diff --git a/engines/ccgost/gost_sign.c b/engines/ccgost/gost_sign.c
index 5bcc296475..b3e1007dbb 100644
--- a/engines/ccgost/gost_sign.c
+++ b/engines/ccgost/gost_sign.c
@@ -13,6 +13,7 @@
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
+#include <openssl/err.h>
#include "gost_params.h"
#include "gost_lcl.h"
@@ -53,11 +54,16 @@ void dump_dsa_sig(const char *message, DSA_SIG *sig)
DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL;
- DSA_SIG *newsig = DSA_SIG_new();
+ DSA_SIG *newsig, *ret = NULL;
BIGNUM *md = hashsum2bn(dgst);
/* check if H(M) mod q is zero */
BN_CTX *ctx = BN_CTX_new();
+ if(!ctx) {
+ GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
BN_CTX_start(ctx);
+ newsig = DSA_SIG_new();
if (!newsig) {
GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
@@ -65,6 +71,10 @@ DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
tmp = BN_CTX_get(ctx);
k = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
+ if(!tmp || !k || !tmp2) {
+ GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
BN_mod(tmp, md, dsa->q, ctx);
if (BN_is_zero(tmp)) {
BN_one(md);
@@ -77,24 +87,41 @@ DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
BN_rand_range(k, dsa->q);
/* generate r = (a^x mod p) mod q */
BN_mod_exp(tmp, dsa->g, k, dsa->p, ctx);
- if (!(newsig->r))
+ if (!(newsig->r)) {
newsig->r = BN_new();
+ if(!newsig->r) {
+ GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
BN_mod(newsig->r, tmp, dsa->q, ctx);
}
while (BN_is_zero(newsig->r));
/* generate s = (xr + k(Hm)) mod q */
BN_mod_mul(tmp, dsa->priv_key, newsig->r, dsa->q, ctx);
BN_mod_mul(tmp2, k, md, dsa->q, ctx);
- if (!newsig->s)
+ if (!newsig->s) {
newsig->s = BN_new();
+ if(!newsig->s) {
+ GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
BN_mod_add(newsig->s, tmp, tmp2, dsa->q, ctx);
}
while (BN_is_zero(newsig->s));
+
+ ret = newsig;
err:
BN_free(md);
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- return newsig;
+ if(ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if(!ret && newsig) {
+ DSA_SIG_free(newsig);
+ }
+ return ret;
}
/*
@@ -136,17 +163,21 @@ int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
int gost_do_verify(const unsigned char *dgst, int dgst_len,
DSA_SIG *sig, DSA *dsa)
{
- BIGNUM *md, *tmp = NULL;
+ BIGNUM *md = NULL, *tmp = NULL;
BIGNUM *q2 = NULL;
BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;
BIGNUM *tmp2 = NULL, *tmp3 = NULL;
int ok;
BN_CTX *ctx = BN_CTX_new();
+ if(!ctx) {
+ GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
BN_CTX_start(ctx);
if (BN_cmp(sig->s, dsa->q) >= 1 || BN_cmp(sig->r, dsa->q) >= 1) {
GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
- return 0;
+ goto err;
}
md = hashsum2bn(dgst);
@@ -158,6 +189,10 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
tmp2 = BN_CTX_get(ctx);
tmp3 = BN_CTX_get(ctx);
u = BN_CTX_get(ctx);
+ if(!tmp || !v || !q2 || !z1 || !z2 || !tmp2 || !tmp3 || !u) {
+ GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
BN_mod(tmp, md, dsa->q, ctx);
if (BN_is_zero(tmp)) {
@@ -175,12 +210,15 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
BN_mod(u, tmp3, dsa->q, ctx);
ok = BN_cmp(u, sig->r);
- BN_free(md);
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
if (ok != 0) {
GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
}
+err:
+ if(md) BN_free(md);
+ if(ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
return (ok == 0);
}
@@ -191,13 +229,24 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
int gost94_compute_public(DSA *dsa)
{
/* Now fill algorithm parameters with correct values */
- BN_CTX *ctx = BN_CTX_new();
+ BN_CTX *ctx;
if (!dsa->g) {
GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITALIZED);
return 0;
}
- /* Compute public key y = a^x mod p */
+ ctx = BN_CTX_new();
+ if(!ctx) {
+ GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
dsa->pub_key = BN_new();
+ if(!dsa->pub_key) {
+ GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+ BN_CTX_free(ctx);
+ return 0;
+ }
+ /* Compute public key y = a^x mod p */
BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx);
BN_CTX_free(ctx);
return 1;
@@ -244,6 +293,10 @@ int fill_GOST94_params(DSA *dsa, int nid)
int gost_sign_keygen(DSA *dsa)
{
dsa->priv_key = BN_new();
+ if(!dsa->priv_key) {
+ GOSTerr(GOST_F_GOST_SIGN_KEYGEN, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
BN_rand_range(dsa->priv_key, dsa->q);
return gost94_compute_public(dsa);
}