Add EC_KEY_oct2priv and EC_KEY_priv2oct
authorDr. Stephen Henson <steve@openssl.org>
Mon, 1 Feb 2016 15:34:13 +0000 (15:34 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 5 Feb 2016 00:33:33 +0000 (00:33 +0000)
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 <viktor@openssl.org>
crypto/ec/ec_key.c
include/openssl/ec.h

index a5c60f680fad358a2c2a0fbee4ea57413d4d2d5c..9fb6a6af135027cd36223fe806fc4e5912dbbb54 100644 (file)
@@ -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;
+}
index 75be82a3209414faee6fdac9c5568dd2c64c68c4..967edf3538f15aee4be4d9a53177961f65eac7d5 100644 (file)
@@ -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          */
 /********************************************************************/