diff options
Diffstat (limited to 'lib/libssl/src')
-rw-r--r-- | lib/libssl/src/crypto/gost/gost89imit_pmeth.c | 12 | ||||
-rw-r--r-- | lib/libssl/src/crypto/gost/gost_locl.h | 4 | ||||
-rw-r--r-- | lib/libssl/src/crypto/gost/gostr341001.c | 256 | ||||
-rw-r--r-- | lib/libssl/src/crypto/gost/gostr341001_ameth.c | 222 | ||||
-rw-r--r-- | lib/libssl/src/crypto/gost/gostr341001_key.c | 28 | ||||
-rw-r--r-- | lib/libssl/src/crypto/gost/gostr341001_pmeth.c | 253 |
6 files changed, 488 insertions, 287 deletions
diff --git a/lib/libssl/src/crypto/gost/gost89imit_pmeth.c b/lib/libssl/src/crypto/gost/gost89imit_pmeth.c index fa79abf0afc..00eaf1decc4 100644 --- a/lib/libssl/src/crypto/gost/gost89imit_pmeth.c +++ b/lib/libssl/src/crypto/gost/gost89imit_pmeth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gost89imit_pmeth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ +/* $OpenBSD: gost89imit_pmeth.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ /* * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Copyright (c) 2005-2006 Cryptocom LTD @@ -115,20 +115,26 @@ pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) } keydata = malloc(32); + if (keydata == NULL) { + GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, ERR_R_MALLOC_FAILURE); + return 0; + } memcpy(keydata, data->key, 32); EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); return 1; } -static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int +pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); switch (type) { case EVP_PKEY_CTRL_MD: if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, + GOST_R_INVALID_DIGEST_TYPE); return 0; } data->md = p2; diff --git a/lib/libssl/src/crypto/gost/gost_locl.h b/lib/libssl/src/crypto/gost/gost_locl.h index 202ba39688c..9036f59771d 100644 --- a/lib/libssl/src/crypto/gost/gost_locl.h +++ b/lib/libssl/src/crypto/gost/gost_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gost_locl.h,v 1.2 2014/11/09 19:27:29 miod Exp $ */ +/* $OpenBSD: gost_locl.h,v 1.3 2014/11/13 20:29:55 miod Exp $ */ /* * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Copyright (c) 2005-2006 Cryptocom LTD @@ -99,7 +99,7 @@ extern int gost2001_compute_public(GOST_KEY *ec); extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); extern int gost2001_keygen(GOST_KEY *ec); -extern void VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, +extern int VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key, const BIGNUM *ukm); extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); diff --git a/lib/libssl/src/crypto/gost/gostr341001.c b/lib/libssl/src/crypto/gost/gostr341001.c index 3c314765f7e..171cf1b80a0 100644 --- a/lib/libssl/src/crypto/gost/gostr341001.c +++ b/lib/libssl/src/crypto/gost/gostr341001.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gostr341001.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */ +/* $OpenBSD: gostr341001.c,v 1.2 2014/11/13 20:29:55 miod Exp $ */ /* * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Copyright (c) 2005-2006 Cryptocom LTD @@ -59,10 +59,12 @@ #include "gost_locl.h" /* Convert little-endian byte array into bignum */ -BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) +BIGNUM * +GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn) { unsigned char temp[64]; int i; + if (len > 64) return NULL; @@ -73,7 +75,8 @@ BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) return BN_bin2bn(temp, len, bn); } -int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) +int +GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len) { unsigned char temp[64]; int i, bytes; @@ -93,8 +96,8 @@ int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) return 1; } - -int gost2001_compute_public(GOST_KEY * ec) +int +gost2001_compute_public(GOST_KEY *ec) { const EC_GROUP *group = GOST_KEY_get0_group(ec); EC_POINT *pub_key = NULL; @@ -102,36 +105,44 @@ int gost2001_compute_public(GOST_KEY * ec) BN_CTX *ctx = NULL; int ok = 0; - if (!group) { + if (group == NULL) { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, - GOST_R_KEY_IS_NOT_INITIALIZED); + GOST_R_KEY_IS_NOT_INITIALIZED); return 0; } ctx = BN_CTX_new(); + if (ctx == NULL) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, + ERR_R_MALLOC_FAILURE); + return 0; + } BN_CTX_start(ctx); - if (!(priv_key = GOST_KEY_get0_private_key(ec))) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL) goto err; - } pub_key = EC_POINT_new(group); - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + if (pub_key == NULL) goto err; - } - if (!GOST_KEY_set_public_key(ec, pub_key)) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0) goto err; - } - ok = 256; + if (GOST_KEY_set_public_key(ec, pub_key) == 0) + goto err; + ok = 1; + + if (ok == 0) { err: - BN_CTX_end(ctx); + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + } EC_POINT_free(pub_key); - BN_CTX_free(ctx); + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } return ok; } -ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) +ECDSA_SIG * +gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey) { ECDSA_SIG *newsig = NULL; BIGNUM *order = NULL; @@ -141,9 +152,15 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) NULL, *e = NULL; EC_POINT *C = NULL; BN_CTX *ctx = BN_CTX_new(); + int ok = 0; + + if (ctx == NULL) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } BN_CTX_start(ctx); newsig = ECDSA_SIG_new(); - if (!newsig) { + if (newsig == NULL) { GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); goto err; } @@ -151,70 +168,88 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) r = newsig->r; group = GOST_KEY_get0_group(eckey); order = BN_CTX_get(ctx); - EC_GROUP_get_order(group, order, ctx); + if (order == NULL) + goto err; + if (EC_GROUP_get_order(group, order, ctx) == 0) + goto err; priv_key = GOST_KEY_get0_private_key(eckey); e = BN_CTX_get(ctx); - BN_mod(e, md, order, ctx); - if (BN_is_zero(e)) { + if (e == NULL) + goto err; + if (BN_mod(e, md, order, ctx) == 0) + goto err; + if (BN_is_zero(e)) BN_one(e); - } k = BN_CTX_get(ctx); X = BN_CTX_get(ctx); C = EC_POINT_new(group); + if (C == NULL) + goto err; do { do { if (!BN_rand_range(k, order)) { GOSTerr(GOST_F_GOST2001_DO_SIGN, GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); - ECDSA_SIG_free(newsig); - newsig = NULL; goto err; } - /* We do not want timing information to leak the length of k, - * so we compute G*k using an equivalent scalar of fixed - * bit-length. */ - if (!BN_add(k, k, order)) + /* + * We do not want timing information to leak the length + * of k, so we compute G*k using an equivalent scalar + * of fixed bit-length. + */ + if (BN_add(k, k, order) == 0) goto err; if (BN_num_bits(k) <= BN_num_bits(order)) - if (!BN_add(k, k, order)) + if (BN_add(k, k, order) == 0) goto err; - if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { + if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) { GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); - ECDSA_SIG_free(newsig); - newsig = NULL; goto err; } - if (!EC_POINT_get_affine_coordinates_GFp - (group, C, X, NULL, ctx)) { + if (EC_POINT_get_affine_coordinates_GFp(group, C, X, + NULL, ctx) == 0) { GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); - ECDSA_SIG_free(newsig); - newsig = NULL; goto err; } - BN_nnmod(r, X, order, ctx); - } - while (BN_is_zero(r)); - /* s = (r*priv_key+k*e) mod order */ - if (!tmp) + if (BN_nnmod(r, X, order, ctx) == 0) + goto err; + } while (BN_is_zero(r)); + /* s = (r*priv_key+k*e) mod order */ + if (tmp == NULL) { tmp = BN_CTX_get(ctx); - BN_mod_mul(tmp, priv_key, r, order, ctx); - if (!tmp2) + if (tmp == NULL) + goto err; + } + if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0) + goto err; + if (tmp2 == NULL) { tmp2 = BN_CTX_get(ctx); - BN_mod_mul(tmp2, k, e, order, ctx); - BN_mod_add(s, tmp, tmp2, order, ctx); - } - while (BN_is_zero(s)); + if (tmp2 == NULL) + goto err; + } + if (BN_mod_mul(tmp2, k, e, order, ctx) == 0) + goto err; + if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0) + goto err; + } while (BN_is_zero(s)); + ok = 1; err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); EC_POINT_free(C); - BN_free(md); + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ok == 0) { + ECDSA_SIG_free(newsig); + newsig = NULL; + } return newsig; } -int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) +int +gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec) { BN_CTX *ctx = BN_CTX_new(); const EC_GROUP *group = GOST_KEY_get0_group(ec); @@ -225,6 +260,8 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) const EC_POINT *pub_key = NULL; int ok = 0; + if (ctx == NULL) + goto err; BN_CTX_start(ctx); order = BN_CTX_get(ctx); e = BN_CTX_get(ctx); @@ -234,88 +271,129 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) X = BN_CTX_get(ctx); R = BN_CTX_get(ctx); v = BN_CTX_get(ctx); + if (v == NULL) + goto err; - EC_GROUP_get_order(group, order, ctx); + if (EC_GROUP_get_order(group, order, ctx) == 0) + goto err; pub_key = GOST_KEY_get0_public_key(ec); 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, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, + GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); goto err; - } - BN_mod(e, md, order, ctx); + if (BN_mod(e, md, order, ctx) == 0) + goto err; if (BN_is_zero(e)) BN_one(e); 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 == NULL) + goto err; + if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0) + goto err; + if (BN_sub(tmp, order, sig->r) == 0) + goto err; + if (BN_mod_mul(z2, tmp, v, order, ctx) == 0) + goto err; C = EC_POINT_new(group); - if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { + if (C == NULL) + goto err; + if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) { GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); goto err; } - if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { + if (EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx) == 0) { 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) == 0) + goto err; if (BN_cmp(R, sig->r) != 0) { GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); } else { ok = 1; } - err: +err: EC_POINT_free(C); - BN_CTX_end(ctx); - BN_CTX_free(ctx); + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } return ok; } - /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ -void VKO_compute_key(BIGNUM * X, BIGNUM * Y, - const GOST_KEY * pkey, GOST_KEY * priv_key, - const BIGNUM * ukm) +int +VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key, + const BIGNUM *ukm) { BIGNUM *p = NULL, *order = NULL; const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); + const EC_GROUP *group = GOST_KEY_get0_group(priv_key); const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); - EC_POINT *pnt = EC_POINT_new(GOST_KEY_get0_group(priv_key)); - BN_CTX *ctx = BN_CTX_new(); + EC_POINT *pnt; + BN_CTX *ctx = NULL; + int ok = 0; + pnt = EC_POINT_new(group); + if (pnt == NULL) + goto err; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; BN_CTX_start(ctx); p = BN_CTX_get(ctx); order = BN_CTX_get(ctx); - EC_GROUP_get_order(GOST_KEY_get0_group(priv_key), order, ctx); - BN_mod_mul(p, key, ukm, order, ctx); - EC_POINT_mul(GOST_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); - EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(priv_key), - pnt, X, Y, ctx); - BN_CTX_end(ctx); - BN_CTX_free(ctx); + if (order == NULL) + goto err; + if (EC_GROUP_get_order(group, order, ctx) == 0) + goto err; + if (BN_mod_mul(p, key, ukm, order, ctx) == 0) + goto err; + if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0) + goto err; + if (EC_POINT_get_affine_coordinates_GFp(group, pnt, X, Y, ctx) == 0) + goto err; + ok = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } EC_POINT_free(pnt); + return ok; } -int gost2001_keygen(GOST_KEY * ec) +int +gost2001_keygen(GOST_KEY *ec) { BIGNUM *order = BN_new(), *d = BN_new(); const EC_GROUP *group = GOST_KEY_get0_group(ec); - EC_GROUP_get_order(group, order, NULL); + int rc = 0; + + if (order == NULL || d == NULL) + goto err; + if (EC_GROUP_get_order(group, order, NULL) == 0) + goto err; do { - if (!BN_rand_range(d, order)) { + if (BN_rand_range(d, order) == 0) { GOSTerr(GOST_F_GOST2001_KEYGEN, GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); - BN_free(d); - BN_free(order); - return 0; + goto err; } } while (BN_is_zero(d)); - GOST_KEY_set_private_key(ec, d); + + if (GOST_KEY_set_private_key(ec, d) == 0) + goto err; + rc = gost2001_compute_public(ec); + +err: BN_free(d); BN_free(order); - return gost2001_compute_public(ec); + return rc; } #endif diff --git a/lib/libssl/src/crypto/gost/gostr341001_ameth.c b/lib/libssl/src/crypto/gost/gostr341001_ameth.c index 710f2aa58c6..243a7490fab 100644 --- a/lib/libssl/src/crypto/gost/gostr341001_ameth.c +++ b/lib/libssl/src/crypto/gost/gostr341001_ameth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gostr341001_ameth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ +/* $OpenBSD: gostr341001_ameth.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ /* * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Copyright (c) 2005-2006 Cryptocom LTD @@ -229,31 +229,34 @@ pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) ASN1_OCTET_STRING_free(octet); ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); - if (!ret) + if (ret == 0) GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); BN_free(X); BN_free(Y); return ret; - } -static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) +static int +pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; + ASN1_STRING *params = NULL; void *pval = NULL; unsigned char *buf = NULL, *sptr; int key_size, ret = 0; const EC_POINT *pub_key; - BIGNUM *X, *Y; + BIGNUM *X = NULL, *Y = NULL; const GOST_KEY *ec = pk->pkey.gost; int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); if (pk->save_parameters) { - ASN1_STRING *params = encode_gost01_algor_params(pk); + params = encode_gost01_algor_params(pk); + if (params == NULL) + return 0; pval = params; ptype = V_ASN1_SEQUENCE; } @@ -261,44 +264,43 @@ static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) key_size = GOST_KEY_get_size(ec); pub_key = GOST_KEY_get0_public_key(ec); - if (!pub_key) { + if (pub_key == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); - return 0; + goto err; } octet = ASN1_OCTET_STRING_new(); - if (!octet) { + if (octet == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } ret = ASN1_STRING_set(octet, NULL, 2 * key_size); - if (!ret) { + if (ret == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); - ASN1_BIT_STRING_free(octet); - return 0; + goto err; } sptr = ASN1_STRING_data(octet); X = BN_new(); Y = BN_new(); - if (!X || !Y) { + if (X == NULL || Y == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - ASN1_BIT_STRING_free(octet); - BN_free(X); - BN_free(Y); - return 0; + goto err; } - EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), - pub_key, X, Y, NULL); + if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), + pub_key, X, Y, NULL) == 0) { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); + goto err; + } GOST_bn2le(X, sptr, key_size); GOST_bn2le(Y, sptr + key_size, key_size); - BN_free(X); BN_free(Y); + BN_free(X); ret = i2d_ASN1_OCTET_STRING(octet, &buf); ASN1_BIT_STRING_free(octet); @@ -306,48 +308,60 @@ static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) return 0; return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); + +err: + BN_free(Y); + BN_free(X); + ASN1_BIT_STRING_free(octet); + ASN1_STRING_free(params); + return 0; } -static int param_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, - ASN1_PCTX * pctx) +static int +param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - int param_nid = EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); - if (!BIO_indent(out, indent, 128)) + int param_nid = + EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); + + if (BIO_indent(out, indent, 128) == 0) return 0; BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); - if (!BIO_indent(out, indent, 128)) + if (BIO_indent(out, indent, 128) == 0) return 0; - BIO_printf(out, "Digest Algorithm: %s\n", OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); + BIO_printf(out, "Digest Algorithm: %s\n", + OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); return 1; } -static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, - ASN1_PCTX * pctx) +static int +pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { BN_CTX *ctx = BN_CTX_new(); BIGNUM *X, *Y; const EC_POINT *pubkey; const EC_GROUP *group; - if (!ctx) { + if (ctx == NULL) { GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE); return 0; } BN_CTX_start(ctx); X = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); + if (X == NULL || Y == NULL) + goto err; pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); group = GOST_KEY_get0_group(pkey->pkey.gost); - if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { + if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, + ctx) == 0) { GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB); - BN_CTX_free(ctx); - return 0; + goto err; } - if (!BIO_indent(out, indent, 128)) - return 0; + if (BIO_indent(out, indent, 128) == 0) + goto err; BIO_printf(out, "Public key:\n"); - if (!BIO_indent(out, indent + 3, 128)) - return 0; + if (BIO_indent(out, indent + 3, 128) == 0) + goto err; BIO_printf(out, "X:"); BN_print(out, X); BIO_printf(out, "\n"); @@ -355,22 +369,28 @@ static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, BIO_printf(out, "Y:"); BN_print(out, Y); BIO_printf(out, "\n"); + BN_CTX_end(ctx); BN_CTX_free(ctx); return param_print_gost01(out, pkey, indent, pctx); + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 0; } -static int priv_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, - ASN1_PCTX * pctx) +static int +priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { const BIGNUM *key; - if (!BIO_indent(out, indent, 128)) + if (BIO_indent(out, indent, 128) == 0) return 0; BIO_printf(out, "Private key: "); key = GOST_KEY_get0_private_key(pkey->pkey.gost); - if (!key) + if (key == NULL) BIO_printf(out, "<undefined)"); else BN_print(out, key); @@ -415,6 +435,7 @@ priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) if (s == NULL || s->length != 32) { GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); + ASN1_STRING_free(s); return 0; } for (i = 0; i < 32; i++) { @@ -424,70 +445,89 @@ priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) pk_num = BN_bin2bn(rev_buf, 32, NULL); } else { priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); - if (!priv_key) + if (priv_key == NULL) return 0; ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); ASN1_INTEGER_free(priv_key); - if (!ret) { + if (ret == 0) { GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); return 0; } } ec = pk->pkey.gost; - if (!ec) { + if (ec == NULL) { ec = GOST_KEY_new(); - EVP_PKEY_assign_GOST(pk, ec); + if (ec == NULL) { + BN_free(pk_num); + return 0; + } + if (EVP_PKEY_assign_GOST(pk, ec) == 0) { + BN_free(pk_num); + GOST_KEY_free(ec); + return 0; + } } - if (!GOST_KEY_set_private_key(ec, pk_num)) { + if (GOST_KEY_set_private_key(ec, pk_num) == 0) { BN_free(pk_num); return 0; } - if (!EVP_PKEY_missing_parameters(pk)) - gost2001_compute_public(ec); + ret = 0; + if (EVP_PKEY_missing_parameters(pk) == 0) + ret = gost2001_compute_public(ec) != 0; BN_free(pk_num); - return 1; + return ret; } -static int priv_encode_gost01(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pk) +static int +priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) { - ASN1_OBJECT *algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); + ASN1_OBJECT *algobj = + OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); ASN1_STRING *params = encode_gost01_algor_params(pk); unsigned char *priv_buf = NULL; int priv_len; - ASN1_INTEGER *asn1key = NULL; - if (!params) { + + if (params == NULL) + return 0; + + asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), + NULL); + if (asn1key == NULL) { + ASN1_STRING_free(params); return 0; } - asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), NULL); priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); ASN1_INTEGER_free(asn1key); - return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, - priv_buf, priv_len); + return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, + priv_len); } -static int param_encode_gost01(const EVP_PKEY * pkey, unsigned char **pder) +static int +param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) { ASN1_STRING *params = encode_gost01_algor_params(pkey); int len; - if (!params) + + if (params == NULL) return 0; len = params->length; - if (pder) + if (pder != NULL) memcpy(*pder, params->data, params->length); ASN1_STRING_free(params); return len; } -static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, - int derlen) +static int +param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { ASN1_OBJECT *obj = NULL; int nid; GOST_KEY *ec; EC_GROUP *group; + int ret; /* New format */ if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) @@ -522,67 +562,85 @@ static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, return 0; } EC_GROUP_free(group); - if (GOST_KEY_set_digest(ec, NID_id_GostR3411_94_CryptoProParamSet) == 0) { + if (GOST_KEY_set_digest(ec, + NID_id_GostR3411_94_CryptoProParamSet) == 0) { GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE); GOST_KEY_free(ec); return 0; } - EVP_PKEY_assign_GOST(pkey, ec); - return 1; + ret = EVP_PKEY_assign_GOST(pkey, ec); + if (ret == 0) + GOST_KEY_free(ec); + return ret; } -static int param_missing_gost01(const EVP_PKEY * pk) +static int +param_missing_gost01(const EVP_PKEY *pk) { const GOST_KEY *ec = pk->pkey.gost; - if (!ec) + + if (ec == NULL) return 1; - if (!GOST_KEY_get0_group(ec)) + if (GOST_KEY_get0_group(ec) == NULL) return 1; if (GOST_KEY_get_digest(ec) == NID_undef) return 1; return 0; } -static int param_copy_gost01(EVP_PKEY * to, const EVP_PKEY * from) +static int +param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) { GOST_KEY *eto = to->pkey.gost; const GOST_KEY *efrom = from->pkey.gost; + int ret = 0; + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { GOSTerr(GOST_F_PARAM_COPY_GOST01, - GOST_R_INCOMPATIBLE_ALGORITHMS); + GOST_R_INCOMPATIBLE_ALGORITHMS); return 0; } - if (!efrom) { + if (efrom == NULL) { GOSTerr(GOST_F_PARAM_COPY_GOST01, - GOST_R_KEY_PARAMETERS_MISSING); + GOST_R_KEY_PARAMETERS_MISSING); return 0; } - if (!eto) { + if (eto) { eto = GOST_KEY_new(); - EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto); + if (eto == NULL) { + GOSTerr(GOST_F_PARAM_COPY_GOST01, + ERR_R_MALLOC_FAILURE); + return 0; + } + if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { + GOST_KEY_free(eto); + return 0; + } } GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); - if (GOST_KEY_get0_private_key(eto)) { - gost2001_compute_public(eto); - } - return 1; + if (GOST_KEY_get0_private_key(eto) != NULL) + ret = gost2001_compute_public(eto); + + return ret; } -static int param_cmp_gost01(const EVP_PKEY * a, const EVP_PKEY * b) +static int +param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) { if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != - EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) { + EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) return 0; - } + if (GOST_KEY_get_digest(a->pkey.gost) != GOST_KEY_get_digest(b->pkey.gost)) return 0; - return 1; + return 1; } -static int pkey_ctrl_gost01(EVP_PKEY * pkey, int op, long arg1, void *arg2) +static int +pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) { X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; int digest = GOST_KEY_get_digest(pkey->pkey.gost); diff --git a/lib/libssl/src/crypto/gost/gostr341001_key.c b/lib/libssl/src/crypto/gost/gostr341001_key.c index b236dde28a9..2405722ddd9 100644 --- a/lib/libssl/src/crypto/gost/gostr341001_key.c +++ b/lib/libssl/src/crypto/gost/gostr341001_key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gostr341001_key.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ +/* $OpenBSD: gostr341001_key.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ /* * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Copyright (c) 2005-2006 Cryptocom LTD @@ -176,45 +176,47 @@ err: return (ok); } -int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y) +int +GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y) { BN_CTX *ctx = NULL; BIGNUM *tx, *ty; EC_POINT *point = NULL; int ok = 0; - if (!key || !key->group || !x || !y) { + if (key == NULL || key->group == NULL || x == NULL || y == NULL) { GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER); return 0; } ctx = BN_CTX_new(); - if (!ctx) + if (ctx == NULL) goto err; point = EC_POINT_new(key->group); - - if (!point) + if (point == NULL) goto err; tx = BN_CTX_get(ctx); ty = BN_CTX_get(ctx); - if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, - x, y, ctx)) + if (ty == NULL) + goto err; + if (EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, + ctx) == 0) goto err; - if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, - tx, ty, ctx)) + if (EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, + ctx) == 0) goto err; /* - * Check if retrieved coordinates match originals: if not values are + * Check if retrieved coordinates match originals: if not, values are * out of range. */ - if (BN_cmp(x, tx) || BN_cmp(y, ty)) { + if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, EC_R_COORDINATES_OUT_OF_RANGE); goto err; } - if (!GOST_KEY_set_public_key(key, point)) + if (GOST_KEY_set_public_key(key, point) == 0) goto err; if (GOST_KEY_check_key(key) == 0) diff --git a/lib/libssl/src/crypto/gost/gostr341001_pmeth.c b/lib/libssl/src/crypto/gost/gostr341001_pmeth.c index afcf8f973a5..859c0884d68 100644 --- a/lib/libssl/src/crypto/gost/gostr341001_pmeth.c +++ b/lib/libssl/src/crypto/gost/gostr341001_pmeth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gostr341001_pmeth.c,v 1.5 2014/11/09 23:06:52 miod Exp $ */ +/* $OpenBSD: gostr341001_pmeth.c,v 1.6 2014/11/13 20:29:55 miod Exp $ */ /* * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Copyright (c) 2005-2006 Cryptocom LTD @@ -133,17 +133,19 @@ struct gost_pmeth_data { int sig_format; }; -static int pkey_gost01_init(EVP_PKEY_CTX * ctx) +static int +pkey_gost01_init(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - data = malloc(sizeof(struct gost_pmeth_data)); - if (!data) + + data = calloc(1, sizeof(struct gost_pmeth_data)); + if (data == NULL) return 0; - memset(data, 0, sizeof(struct gost_pmeth_data)); - if (pkey && pkey->pkey.gost) { - data->sign_param_nid = EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); + if (pkey != NULL && pkey->pkey.gost != NULL) { + data->sign_param_nid = + EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost); } EVP_PKEY_CTX_set_data(ctx, data); @@ -151,85 +153,95 @@ static int pkey_gost01_init(EVP_PKEY_CTX * ctx) } /* Copies contents of gost_pmeth_data structure */ -static int pkey_gost01_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src) +static int +pkey_gost01_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { struct gost_pmeth_data *dst_data, *src_data; - if (!pkey_gost01_init(dst)) { + + if (pkey_gost01_init(dst) == 0) return 0; - } + src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); *dst_data = *src_data; - if (src_data->shared_ukm) { + if (src_data->shared_ukm != NULL) dst_data->shared_ukm = NULL; - } return 1; } /* Frees up gost_pmeth_data structure */ -static void pkey_gost01_cleanup(EVP_PKEY_CTX * ctx) +static void +pkey_gost01_cleanup(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + free(data->shared_ukm); free(data); } -static int pkey_gost01_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) +static int +pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EC_GROUP *group; GOST_KEY *gost; int ret; - if (data->sign_param_nid == NID_undef || data->digest_nid == NID_undef) { + if (data->sign_param_nid == NID_undef || + data->digest_nid == NID_undef) { GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); return 0; } group = EC_GROUP_new_by_curve_name(data->sign_param_nid); - if (!group) + if (group == NULL) return 0; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); gost = GOST_KEY_new(); - if (!gost) + if (gost == NULL) return 0; - if (!GOST_KEY_set_digest(gost, data->digest_nid)) + if (GOST_KEY_set_digest(gost, data->digest_nid) == 0) return 0; ret = GOST_KEY_set_group(gost, group); - if (ret) - EVP_PKEY_assign_GOST(pkey, gost); - else + if (ret != 0) + ret = EVP_PKEY_assign_GOST(pkey, gost); + if (ret == 0) GOST_KEY_free(gost); EC_GROUP_free(group); return ret; } -static int pkey_gost01_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) +static int +pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - if (!pkey_gost01_paramgen(ctx, pkey)) + if (pkey_gost01_paramgen(ctx, pkey) == 0) return 0; - gost2001_keygen(pkey->pkey.gost); - return 1; + return gost2001_keygen(pkey->pkey.gost) != 0; } -static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, - size_t * siglen, const unsigned char *tbs, - size_t tbs_len) +static int +pkey_gost01_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbs_len) { ECDSA_SIG *unpacked_sig = NULL; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); BIGNUM *md; - size_t size = GOST_KEY_get_size(pkey->pkey.gost); + size_t size; + int ret; + + if (pkey == NULL || pkey->pkey.gost == NULL) + return 0; + size = GOST_KEY_get_size(pkey->pkey.gost); - if (!siglen) + if (siglen == NULL) return 0; - if (!sig) { + if (sig == NULL) { *siglen = 2 * size; return 1; } else if (*siglen < 2 * size) { @@ -238,24 +250,32 @@ static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, } OPENSSL_assert(tbs_len == 32 || tbs_len == 64); md = GOST_le2bn(tbs, tbs_len, NULL); + if (md == NULL) + return 0; unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost); - if (!unpacked_sig) { + BN_free(md); + if (unpacked_sig == NULL) { return 0; } switch (pctx->sig_format) { case GOST_SIG_FORMAT_SR_BE: - return pack_signature_cp(unpacked_sig, size, sig, siglen); + ret = pack_signature_cp(unpacked_sig, size, sig, siglen); + break; case GOST_SIG_FORMAT_RS_LE: - return pack_signature_le(unpacked_sig, size, sig, siglen); + ret = pack_signature_le(unpacked_sig, size, sig, siglen); + break; default: - ECDSA_SIG_free(unpacked_sig); - return -1; + ret = -1; + break; } + if (ret <= 0) + ECDSA_SIG_free(unpacked_sig); + return ret; } -static int pkey_gost01_verify(EVP_PKEY_CTX * ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbs_len) +static int +pkey_gost01_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbs_len) { int ok = 0; EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); @@ -286,24 +306,33 @@ err: return ok; } -static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, - const unsigned char *ukm, unsigned char *key) +static int +gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm, + unsigned char *key) { unsigned char hashbuf[128]; int digest_nid; - int ret; + int ret = 0; BN_CTX *ctx = BN_CTX_new(); BIGNUM *UKM, *X, *Y; + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); UKM = BN_CTX_get(ctx); X = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); + if (Y == NULL) + goto err; GOST_le2bn(ukm, 8, UKM); digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost); - VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, UKM); + if (VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, + UKM) == 0) + goto err; + switch (digest_nid) { case NID_id_GostR3411_94_CryptoProParamSet: GOST_bn2le(X, hashbuf, 32); @@ -327,14 +356,15 @@ static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, ret = -2; break; } +err: BN_CTX_end(ctx); BN_CTX_free(ctx); return ret; } -int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, - size_t * key_len, const unsigned char *in, - size_t in_len) +int +pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, + const unsigned char *in, size_t in_len) { const unsigned char *p = in; EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); @@ -387,26 +417,26 @@ int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); OPENSSL_assert(gkt->key_info->imit->length == 4); memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); - gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey); - if (!gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key)) { + if (gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey) <= 0) + goto err; + if (gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key) == 0) { GOSTerr(GOST_F_PKEY_GOST01_DECRYPT, - GOST_R_ERROR_COMPUTING_SHARED_KEY); + GOST_R_ERROR_COMPUTING_SHARED_KEY); goto err; } ret = 1; - err: - if (eph_key) - EVP_PKEY_free(eph_key); - if (gkt) - GOST_KEY_TRANSPORT_free(gkt); +err: + EVP_PKEY_free(eph_key); + GOST_KEY_TRANSPORT_free(gkt); return ret; } -int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, - size_t * keylen) +int +pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { - /* Public key of peer in the ctx field peerkey + /* + * Public key of peer in the ctx field peerkey * Our private key in the ctx pkey * ukm is in the algorithm specific context data */ @@ -424,86 +454,98 @@ int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, return 32; } - gost01_VKO_key(peer_key, my_key, data->shared_ukm, key); + if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, key) <= 0) + return 0; + *keylen = 32; return 1; } -int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, - size_t * out_len, const unsigned char *key, - size_t key_len) +int +pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, + const unsigned char *key, size_t key_len) { GOST_KEY_TRANSPORT *gkt = NULL; EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); unsigned char ukm[8], shared_key[32], crypted_key[44]; int ret = 0; - int key_is_ephemeral = 1; + int key_is_ephemeral; EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; - if (data->shared_ukm) { + if (data->shared_ukm != NULL) { memcpy(ukm, data->shared_ukm, 8); - } else if (out) { + } else /* if (out != NULL) */ { arc4random_buf(ukm, 8); } /* Check for private key in the peer_key of context */ if (sec_key) { key_is_ephemeral = 0; - if (!GOST_KEY_get0_private_key(sec_key->pkey.gost)) { + if (GOST_KEY_get0_private_key(sec_key->pkey.gost) == 0) { GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, - GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); goto err; } } else { key_is_ephemeral = 1; - if (out) { + if (out != NULL) { + GOST_KEY *tmp_key; + sec_key = EVP_PKEY_new(); - EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), - GOST_KEY_new()); - EVP_PKEY_copy_parameters(sec_key, pubk); - if (!gost2001_keygen(sec_key->pkey.gost)) { + if (sec_key == NULL) + goto err; + tmp_key = GOST_KEY_new(); + if (tmp_key == NULL) + goto err; + if (EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), + tmp_key) == 0) { + GOST_KEY_free(tmp_key); + goto err; + } + if (EVP_PKEY_copy_parameters(sec_key, pubk) == 0) + goto err; + if (gost2001_keygen(sec_key->pkey.gost) == 0) { goto err; } } } - if (out) { - gost01_VKO_key(pubk, sec_key, ukm, shared_key); - gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, crypted_key); + if (out != NULL) { + if (gost01_VKO_key(pubk, sec_key, ukm, shared_key) <= 0) + goto err; + gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, + crypted_key); } gkt = GOST_KEY_TRANSPORT_new(); - if (!gkt) { + if (gkt == NULL) goto err; - } - if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { + if (ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) == 0) goto err; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { + if (ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, + 4) == 0) goto err; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, 32)) { + if (ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, + 32) == 0) goto err; - } if (key_is_ephemeral) { - if (!X509_PUBKEY_set - (&gkt->key_agreement_info->ephem_key, - out ? sec_key : pubk)) { + if (X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key, + out != NULL ? sec_key : pubk) == 0) { GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, - GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; } } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(nid); - if (key_is_ephemeral && sec_key) + if (key_is_ephemeral) EVP_PKEY_free(sec_key); - if (!key_is_ephemeral) { + else { /* Set control "public key from client certificate used" */ - if (EVP_PKEY_CTX_ctrl - (pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, + NULL) <= 0) { GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, - GOST_R_CTRL_CALL_FAILED); + GOST_R_CTRL_CALL_FAILED); goto err; } } @@ -511,21 +553,26 @@ int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, ret = 1; GOST_KEY_TRANSPORT_free(gkt); return ret; - err: - if (key_is_ephemeral && sec_key) + +err: + if (key_is_ephemeral) EVP_PKEY_free(sec_key); GOST_KEY_TRANSPORT_free(gkt); return -1; } -static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) +static int +pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); + switch (type) { case EVP_PKEY_CTRL_MD: - if (EVP_MD_type(p2) != GostR3410_get_md_digest(pctx->digest_nid)) { - GOSTerr(GOST_F_PKEY_GOST01_CTRL, GOST_R_INVALID_DIGEST_TYPE); + if (EVP_MD_type(p2) != + GostR3410_get_md_digest(pctx->digest_nid)) { + GOSTerr(GOST_F_PKEY_GOST01_CTRL, + GOST_R_INVALID_DIGEST_TYPE); return 0; } pctx->md = p2; @@ -546,9 +593,19 @@ static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_SET_IV: - pctx->shared_ukm = malloc((int)p1); - memcpy(pctx->shared_ukm, p2, (int)p1); + { + char *ukm = malloc(p1); + + if (ukm == NULL) { + GOSTerr(GOST_F_PKEY_GOST01_CTRL, + ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(ukm, p2, p1); + free(pctx->shared_ukm); + pctx->shared_ukm = ukm; return 1; + } case EVP_PKEY_CTRL_PEER_KEY: if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ |