From 981bd8a2f28c17f774ecb8b60233858fe52db502 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sat, 12 Dec 2015 01:04:25 +0000 Subject: [PATCH] New EC functions. New functions EC_POINT_point2buf and EC_KEY_key2buf which encode a point and allocate a buffer in one call. New function EC_KEY_oct2key() which sets public key in an EC_KEY structure from an encoded point. Reviewed-by: Richard Levitte --- crypto/ec/ec_asn1.c | 10 +--------- crypto/ec/ec_key.c | 20 ++++++++++++++++++++ crypto/ec/ec_oct.c | 21 +++++++++++++++++++++ crypto/ec/ec_print.c | 24 +++++------------------- include/openssl/ec.h | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 28 deletions(-) diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 4206d77984..05cdfbf64b 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -578,19 +578,11 @@ static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, form = EC_GROUP_get_point_conversion_form(group); - len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); + len = EC_POINT_point2buf(group, point, form, &buffer, NULL); if (len == 0) { ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); goto err; } - if ((buffer = OPENSSL_malloc(len)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); - goto err; - } if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); goto err; diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index ac661eddd8..e2ca142057 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -575,3 +575,23 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags) { key->flags &= ~flags; } + +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx) +{ + if (key == NULL || key->pub_key == NULL || key->group == NULL) + return 0; + return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx); +} + +int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, + BN_CTX *ctx) +{ + if (key == NULL || key->group == NULL) + return 0; + if (key->pub_key == NULL) + key->pub_key = EC_POINT_new(key->group); + if (key->pub_key == NULL) + return 0; + return EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx); +} diff --git a/crypto/ec/ec_oct.c b/crypto/ec/ec_oct.c index 040c414a33..fca50dc6bf 100644 --- a/crypto/ec/ec_oct.c +++ b/crypto/ec/ec_oct.c @@ -190,3 +190,24 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, } return group->meth->oct2point(group, point, buf, len, ctx); } + +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx) +{ + size_t len; + unsigned char *buf; + len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL); + if (len == 0) + return 0; + buf = OPENSSL_malloc(len); + if (buf == NULL) + return 0; + len = EC_POINT_point2oct(group, point, form, buf, len, ctx); + if (len == 0) { + OPENSSL_free(buf); + return 0; + } + *pbuf = buf; + return len; +} diff --git a/crypto/ec/ec_print.c b/crypto/ec/ec_print.c index 5ae85ccdb0..7bc0760c5b 100644 --- a/crypto/ec/ec_print.c +++ b/crypto/ec/ec_print.c @@ -64,17 +64,10 @@ BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, size_t buf_len = 0; unsigned char *buf; - buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); - if (buf_len == 0) - return NULL; - - if ((buf = OPENSSL_malloc(buf_len)) == NULL) - return NULL; + buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx); - if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { - OPENSSL_free(buf); + if (buf_len == 0) return NULL; - } ret = BN_bin2bn(buf, buf_len, ret); @@ -129,19 +122,12 @@ char *EC_POINT_point2hex(const EC_GROUP *group, { char *ret, *p; size_t buf_len = 0, i; - unsigned char *buf, *pbuf; + unsigned char *buf = NULL, *pbuf; - buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); - if (buf_len == 0) - return NULL; - - if ((buf = OPENSSL_malloc(buf_len)) == NULL) - return NULL; + buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx); - if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { - OPENSSL_free(buf); + if (buf_len == 0) return NULL; - } ret = OPENSSL_malloc(buf_len * 2 + 2); if (ret == NULL) { diff --git a/include/openssl/ec.h b/include/openssl/ec.h index a7793b8271..33f1c7319e 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -589,6 +589,20 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, const unsigned char *buf, size_t len, BN_CTX *ctx); +/** Encodes an EC_POINT object to an allocated octet string + * \param group underlying EC_GROUP object + * \param point EC_POINT object + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ + +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + /* other interfaces to point2oct/oct2point: */ BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, BIGNUM *, BN_CTX *); @@ -887,6 +901,29 @@ int EC_KEY_check_key(const EC_KEY *key); int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y); +/** Encodes an EC_KEY public key to an allocated octet string + * \param key key to encode + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ + +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/** Decodes a EC_KEY public key from a octet string + * \param key key to decode + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, + BN_CTX *ctx); + /********************************************************************/ /* de- and encoding functions for SEC1 ECPrivateKey */ /********************************************************************/ -- 2.34.1