summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2016-02-01 15:34:13 +0000
committerDr. Stephen Henson <steve@openssl.org>2016-02-05 00:33:33 +0000
commitcf2413955cafcfe98d8292f996a87ef55b777caa (patch)
tree81d4e423646462cbbad98563d0c77c92663a54a2
parent26c255fcf875d0272349c1221780dcd7e67b5d61 (diff)
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 <viktor@openssl.org>
-rw-r--r--crypto/ec/ec_key.c53
-rw-r--r--include/openssl/ec.h20
2 files changed, 73 insertions, 0 deletions
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 */
/********************************************************************/