From cf2413955cafcfe98d8292f996a87ef55b777caa Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 1 Feb 2016 15:34:13 +0000 Subject: [PATCH] Add EC_KEY_oct2priv and EC_KEY_priv2oct New functions EC_KEY_oct2priv and EC_KEY_priv2oct. These are private key equivalents of EC_POINT_oct2point and EC_POINT_point2oct which convert between the private key octet format and EC_KEY. Reviewed-by: Viktor Dukhovni --- crypto/ec/ec_key.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ include/openssl/ec.h | 20 +++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index a5c60f680f..9fb6a6af13 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -548,3 +548,56 @@ int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, return 0; return EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx); } + +size_t EC_KEY_priv2oct(const EC_KEY *eckey, unsigned char *buf, size_t len) +{ + size_t buf_len, bn_len; + if (eckey->group == NULL || eckey->group->meth == NULL) + return 0; + + buf_len = (EC_GROUP_get_degree(eckey->group) + 7) / 8; + if (eckey->priv_key == NULL) + return 0; + if (buf == NULL) + return buf_len; + else if (len < buf_len) + return 0; + + bn_len = (size_t)BN_num_bytes(eckey->priv_key); + + /* Octetstring may need leading zeros if BN is to short */ + + if (bn_len > buf_len) { + ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!BN_bn2bin(eckey->priv_key, buf + buf_len - bn_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); + return 0; + } + + if (buf_len - bn_len > 0) + memset(buf, 0, buf_len - bn_len); + + return buf_len; +} + +int EC_KEY_oct2priv(EC_KEY *eckey, unsigned char *buf, size_t len) +{ + if (eckey->group == NULL || eckey->group->meth == NULL) + return 0; + + if (eckey->priv_key == NULL) + eckey->priv_key = BN_secure_new(); + if (eckey->priv_key == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key); + if (eckey->priv_key == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); + return 0; + } + return 1; +} diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 75be82a320..967edf3538 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -934,6 +934,26 @@ size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, BN_CTX *ctx); +/** Decodes an EC_KEY private key from an octet string + * \param key key to decode + * \param buf memory buffer with the encoded private key + * \param len length of the encoded key + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2priv(EC_KEY *key, unsigned char *buf, size_t len); + +/** Encodes a EC_KEY private key to an octet string + * \param key key to encode + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ + +size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len); + + /********************************************************************/ /* de- and encoding functions for SEC1 ECPrivateKey */ /********************************************************************/ -- 2.40.0