[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Fri Feb 5 00:37:16 UTC 2016


The branch master has been updated
       via  141c6095f22c0d0bc957727eccfa83356f32e090 (commit)
       via  7fc7d1a7bdeda7e448c13e6fecce96a53b7a62d2 (commit)
       via  ac3e3665016e4441475276461d5f910eb9e9ea15 (commit)
       via  907e95006820c84d2efe1adb2c8af8340f3ba6cc (commit)
       via  d6755bb6ac6676cf0f219cd4caf352ac48907206 (commit)
       via  d810700b80104c349244221af9ce794294b8aeb3 (commit)
       via  cf2413955cafcfe98d8292f996a87ef55b777caa (commit)
       via  26c255fcf875d0272349c1221780dcd7e67b5d61 (commit)
      from  d698550fb41c3fd1e5c4c8fc6bed37cd8931467d (commit)


- Log -----------------------------------------------------------------
commit 141c6095f22c0d0bc957727eccfa83356f32e090
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Feb 4 23:23:02 2016 +0000

    make update
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

commit 7fc7d1a7bdeda7e448c13e6fecce96a53b7a62d2
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Feb 4 23:18:57 2016 +0000

    Add EC_KEY_priv2buf()
    
    Add new function EC_KEY_priv2buf() to allocated and encode private
    key octet in one call. Update and simplify ASN.1 and print routines.
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

commit ac3e3665016e4441475276461d5f910eb9e9ea15
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Feb 4 18:53:07 2016 +0000

    Allocate ASN1_bn_print buffer internally.
    
    Don't require an application to work out the appropriate buffer size for
    ASN1_bn_print(), which is unsafe. Ignore the supplied buffer and allocate
    it internally instead.
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

commit 907e95006820c84d2efe1adb2c8af8340f3ba6cc
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Feb 3 18:51:02 2016 +0000

    Use BN_bn2binpad
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

commit d6755bb6ac6676cf0f219cd4caf352ac48907206
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Feb 3 14:53:15 2016 +0000

    use enum type for do_EC_KEY_print
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

commit d810700b80104c349244221af9ce794294b8aeb3
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Feb 1 15:46:29 2016 +0000

    update EC ASN1 and print routines
    
    Update EC ASN.1 and print routines to use EC_KEY_oct2priv and
    EC_KEY_priv2oct.
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

commit cf2413955cafcfe98d8292f996a87ef55b777caa
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Feb 1 15:34:13 2016 +0000

    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 at openssl.org>

commit 26c255fcf875d0272349c1221780dcd7e67b5d61
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Jan 27 14:34:36 2016 +0000

    Add ASN1_buf_print to print a buffer in ASN1_bn_print format.
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/t_pkey.c   | 88 ++++++++++++++++++++++++++++++---------------
 crypto/ec/ec_ameth.c   | 98 ++++++++++++++++++++++----------------------------
 crypto/ec/ec_asn1.c    | 78 ++++++++++------------------------------
 crypto/ec/ec_err.c     | 14 +++++++-
 crypto/ec/ec_key.c     | 62 ++++++++++++++++++++++++++++++++
 include/openssl/asn1.h |  1 +
 include/openssl/ec.h   | 29 +++++++++++++++
 util/libeay.num        |  4 +++
 8 files changed, 229 insertions(+), 145 deletions(-)

diff --git a/crypto/asn1/t_pkey.c b/crypto/asn1/t_pkey.c
index c50d193..b17862c 100644
--- a/crypto/asn1/t_pkey.c
+++ b/crypto/asn1/t_pkey.c
@@ -61,16 +61,47 @@
 #include <openssl/buffer.h>
 #include "internal/bn_int.h"
 
+/* Number of octets per line */
+#define ASN1_BUF_PRINT_WIDTH    15
+/* Maximum indent */
+#define ASN1_PRINT_MAX_INDENT 128
+
+int ASN1_buf_print(BIO *bp, unsigned char *buf, size_t buflen, int indent)
+{
+    size_t i;
+
+    for (i = 0; i < buflen; i++) {
+        if ((i % ASN1_BUF_PRINT_WIDTH) == 0) {
+            if (i > 0 && BIO_puts(bp, "\n") <= 0)
+                return 0;
+            if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
+                return 0;
+        }
+        /*
+         * Use colon separators for each octet for compatibility as
+         * this fuction is used to print out key components.
+         */
+        if (BIO_printf(bp, "%02x%s", buf[i],
+                       (i == buflen - 1) ? "" : ":") <= 0)
+                return 0;
+    }
+    if (BIO_write(bp, "\n", 1) <= 0)
+        return 0;
+    return 1;
+}
+
 int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
-                  unsigned char *buf, int off)
+                  unsigned char *ign, int indent)
 {
-    int n, i;
+    int n, rv = 0;
     const char *neg;
+    unsigned char *buf = NULL, *tmp = NULL;
+    int buflen;
 
     if (num == NULL)
-        return (1);
-    neg = (BN_is_negative(num)) ? "-" : "";
-    if (!BIO_indent(bp, off, 128))
+        return 1;
+    neg = BN_is_negative(num) ? "-" : "";
+    if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
         return 0;
     if (BN_is_zero(num)) {
         if (BIO_printf(bp, "%s 0\n", number) <= 0)
@@ -82,30 +113,29 @@ int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
         if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
                        (unsigned long)bn_get_words(num)[0], neg,
                        (unsigned long)bn_get_words(num)[0]) <= 0)
-            return (0);
-    } else {
-        buf[0] = 0;
-        if (BIO_printf(bp, "%s%s", number,
-                       (neg[0] == '-') ? " (Negative)" : "") <= 0)
-            return (0);
-        n = BN_bn2bin(num, &buf[1]);
+            return 0;
+        return 1;
+    }
 
-        if (buf[1] & 0x80)
-            n++;
-        else
-            buf++;
+    buflen = BN_num_bytes(num) + 1;
+    buf = tmp = OPENSSL_malloc(buflen);
+    if (buf == NULL)
+        goto err;
+    buf[0] = 0;
+    if (BIO_printf(bp, "%s%s\n", number,
+                   (neg[0] == '-') ? " (Negative)" : "") <= 0)
+        goto err;
+    n = BN_bn2bin(num, buf + 1);
 
-        for (i = 0; i < n; i++) {
-            if ((i % 15) == 0) {
-                if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128))
-                    return 0;
-            }
-            if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":")
-                <= 0)
-                return (0);
-        }
-        if (BIO_write(bp, "\n", 1) <= 0)
-            return (0);
-    }
-    return (1);
+    if (buf[1] & 0x80)
+        n++;
+    else
+        tmp++;
+
+    if (ASN1_buf_print(bp, tmp, n, indent + 4) == 0)
+        goto err;
+    rv = 1;
+    err:
+    OPENSSL_clear_free(buf, buflen);
+    return rv;
 }
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 2e43f1d..9420875 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -379,59 +379,40 @@ static void int_ec_free(EVP_PKEY *pkey)
     EC_KEY_free(pkey->pkey.ec);
 }
 
-static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
+typedef enum {
+    EC_KEY_PRINT_PRIVATE,
+    EC_KEY_PRINT_PUBLIC,
+    EC_KEY_PRINT_PARAM
+} ec_print_t;
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
 {
-    unsigned char *buffer = NULL;
     const char *ecstr;
-    size_t buf_len = 0, i;
-    int ret = 0, reason = ERR_R_BIO_LIB;
-    BIGNUM *pub_key = NULL;
-    BN_CTX *ctx = NULL;
+    unsigned char *priv = NULL, *pub = NULL;
+    size_t privlen = 0, publen = 0;
+    int ret = 0;
     const EC_GROUP *group;
-    const EC_POINT *public_key;
-    const BIGNUM *priv_key;
 
     if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
-        reason = ERR_R_PASSED_NULL_PARAMETER;
-        goto err;
-    }
-
-    ctx = BN_CTX_new();
-    if (ctx == NULL) {
-        reason = ERR_R_MALLOC_FAILURE;
-        goto err;
+        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
     }
 
-    if (ktype > 0) {
-        public_key = EC_KEY_get0_public_key(x);
-        if (public_key != NULL) {
-            if ((pub_key = EC_POINT_point2bn(group, public_key,
-                                             EC_KEY_get_conv_form(x), NULL,
-                                             ctx)) == NULL) {
-                reason = ERR_R_EC_LIB;
-                goto err;
-            }
-            buf_len = (size_t)BN_num_bytes(pub_key);
-        }
+    if (ktype != EC_KEY_PRINT_PARAM) {
+        publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
+        if (publen == 0)
+            goto err;
     }
 
-    if (ktype == 2) {
-        priv_key = EC_KEY_get0_private_key(x);
-        if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
-            buf_len = i;
-    } else
-        priv_key = NULL;
-
-    if (ktype > 0) {
-        buf_len += 10;
-        if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
-            reason = ERR_R_MALLOC_FAILURE;
+    if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
+        privlen = EC_KEY_priv2buf(x, &priv);
+        if (privlen == 0)
             goto err;
-        }
     }
-    if (ktype == 2)
+
+    if (ktype == EC_KEY_PRINT_PRIVATE)
         ecstr = "Private-Key";
-    else if (ktype == 1)
+    else if (ktype == EC_KEY_PRINT_PUBLIC)
         ecstr = "Public-Key";
     else
         ecstr = "ECDSA-Parameters";
@@ -442,22 +423,29 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
                    EC_GROUP_order_bits(group)) <= 0)
         goto err;
 
-    if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
-                                             buffer, off))
-        goto err;
-    if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
-                                            buffer, off))
-        goto err;
+    if (privlen != 0) {
+        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
+            goto err;
+        if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
+            goto err;
+    }
+
+    if (publen != 0) {
+        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
+            goto err;
+        if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
+            goto err;
+    }
+
     if (!ECPKParameters_print(bp, group, off))
         goto err;
     ret = 1;
  err:
     if (!ret)
-        ECerr(EC_F_DO_EC_KEY_PRINT, reason);
-    BN_free(pub_key);
-    BN_CTX_free(ctx);
-    OPENSSL_free(buffer);
-    return (ret);
+        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
+    OPENSSL_clear_free(priv, privlen);
+    OPENSSL_free(pub);
+    return ret;
 }
 
 static int eckey_param_decode(EVP_PKEY *pkey,
@@ -481,19 +469,19 @@ static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                              ASN1_PCTX *ctx)
 {
-    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
 }
 
 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                            ASN1_PCTX *ctx)
 {
-    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
 }
 
 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                             ASN1_PCTX *ctx)
 {
-    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
 }
 
 static int old_ec_priv_decode(EVP_PKEY *pkey,
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 842f9c3..fe2a979 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -1013,19 +1013,10 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
     ret->version = priv_key->version;
 
     if (priv_key->privateKey) {
-        if (ret->priv_key == NULL)
-            ret->priv_key = BN_secure_new();
-        if (ret->priv_key == NULL) {
-            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
-            goto err;
-        }
-        ret->priv_key = BN_bin2bn(ASN1_STRING_data(priv_key->privateKey),
-                                  ASN1_STRING_length(priv_key->privateKey),
-                                  ret->priv_key);
-        if (ret->priv_key == NULL) {
-            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB);
+        ASN1_OCTET_STRING *pkey = priv_key->privateKey;
+        if (EC_KEY_oct2priv(ret, ASN1_STRING_data(pkey),
+                            ASN1_STRING_length(pkey)) == 0)
             goto err;
-        }
     } else {
         ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
         goto err;
@@ -1084,11 +1075,12 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
 int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
 {
     int ret = 0, ok = 0;
-    unsigned char *buffer = NULL;
-    size_t buf_len = 0, tmp_len, bn_len;
+    unsigned char *priv= NULL, *pub= NULL;
+    size_t privlen, publen;
+
     EC_PRIVATEKEY *priv_key = NULL;
 
-    if (a == NULL || a->group == NULL || a->priv_key == NULL ||
+    if (a == NULL || a->group == NULL ||
         (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
         goto err;
@@ -1101,36 +1093,15 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
 
     priv_key->version = a->version;
 
-    bn_len = (size_t)BN_num_bytes(a->priv_key);
-
-    /* Octetstring may need leading zeros if BN is to short */
+    privlen = EC_KEY_priv2buf(a, &priv);
 
-    buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8;
-
-    if (bn_len > buf_len) {
-        ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
-        goto err;
-    }
-
-    buffer = OPENSSL_malloc(buf_len);
-    if (buffer == NULL) {
-        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
-        goto err;
-    }
-
-    if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) {
-        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
+    if (privlen == 0) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
         goto err;
     }
 
-    if (buf_len - bn_len > 0) {
-        memset(buffer, 0, buf_len - bn_len);
-    }
-
-    if (!ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
-        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
-        goto err;
-    }
+    ASN1_STRING_set0(priv_key->privateKey, priv, privlen);
+    priv = NULL;
 
     if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
         if ((priv_key->parameters =
@@ -1148,31 +1119,17 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
             goto err;
         }
 
-        tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
-                                     a->conv_form, NULL, 0, NULL);
+        publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL);
 
-        if (tmp_len > buf_len) {
-            unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
-            if (!tmp_buffer) {
-                ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
-                goto err;
-            }
-            buffer = tmp_buffer;
-            buf_len = tmp_len;
-        }
-
-        if (!EC_POINT_point2oct(a->group, a->pub_key,
-                                a->conv_form, buffer, buf_len, NULL)) {
+        if (publen == 0) {
             ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
             goto err;
         }
 
         priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
         priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-        if (!ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
-            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
-            goto err;
-        }
+        ASN1_STRING_set0(priv_key->publicKey, pub, publen);
+        pub = NULL;
     }
 
     if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
@@ -1181,7 +1138,8 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
     }
     ok = 1;
  err:
-    OPENSSL_free(buffer);
+    OPENSSL_clear_free(priv, privlen);
+    OPENSSL_free(pub);
     EC_PRIVATEKEY_free(priv_key);
     return (ok ? ret : 0);
 }
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index 4811fa2..b4edc21 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -1,5 +1,6 @@
+/* crypto/ec/ec_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2015 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -77,6 +78,12 @@ static ERR_STRING_DATA EC_str_functs[] = {
     {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "do_EC_KEY_print"},
     {ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ecdh_cms_decrypt"},
     {ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ecdh_cms_set_shared_info"},
+    {ERR_FUNC(EC_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
+    {ERR_FUNC(EC_F_ECDSA_DO_SIGN_EX), "ECDSA_do_sign_ex"},
+    {ERR_FUNC(EC_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
+    {ERR_FUNC(EC_F_ECDSA_SIGN_EX), "ECDSA_sign_ex"},
+    {ERR_FUNC(EC_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
+    {ERR_FUNC(EC_F_ECDSA_VERIFY), "ECDSA_verify"},
     {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "eckey_param2type"},
     {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "eckey_param_decode"},
     {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "eckey_priv_decode"},
@@ -200,8 +207,10 @@ static ERR_STRING_DATA EC_str_functs[] = {
     {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
     {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
     {ERR_FUNC(EC_F_EC_KEY_NEW_METHOD), "EC_KEY_new_method"},
+    {ERR_FUNC(EC_F_EC_KEY_OCT2PRIV), "EC_KEY_oct2priv"},
     {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
     {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
+    {ERR_FUNC(EC_F_EC_KEY_PRIV2OCT), "EC_KEY_priv2oct"},
     {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
      "EC_KEY_set_public_key_affine_coordinates"},
     {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
@@ -247,6 +256,9 @@ static ERR_STRING_DATA EC_str_functs[] = {
     {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "nistp521_pre_comp_new"},
     {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
     {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "old_ec_priv_decode"},
+    {ERR_FUNC(EC_F_OSSL_ECDH_COMPUTE_KEY), "ossl_ecdh_compute_key"},
+    {ERR_FUNC(EC_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"},
+    {ERR_FUNC(EC_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"},
     {ERR_FUNC(EC_F_PKEY_EC_CTRL), "pkey_ec_ctrl"},
     {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "pkey_ec_ctrl_str"},
     {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "pkey_ec_derive"},
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index a5c60f6..57388da 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -548,3 +548,65 @@ 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;
+    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;
+
+    /* Octetstring may need leading zeros if BN is to short */
+
+    if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
+        ECerr(EC_F_EC_KEY_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
+        return 0;
+    }
+
+    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_EC_KEY_OCT2PRIV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key);
+    if (eckey->priv_key == NULL) {
+        ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_BN_LIB);
+        return 0;
+    }
+    return 1;
+}
+
+size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
+{
+    size_t len;
+    unsigned char *buf;
+    len = EC_KEY_priv2oct(eckey, NULL, 0);
+    if (len == 0)
+        return 0;
+    buf = OPENSSL_malloc(len);
+    if (buf == NULL)
+        return 0;
+    len = EC_KEY_priv2oct(eckey, buf, len);
+    if (len == 0) {
+        OPENSSL_free(buf);
+        return 0;
+    }
+    *pbuf = buf;
+    return len;
+}
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index 63253d4..360914d 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -785,6 +785,7 @@ int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
 int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
 int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
 int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_buf_print(BIO *bp, unsigned char *buf, size_t buflen, int off);
 int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
                   unsigned char *buf, int off);
 int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent);
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 75be82a..e39704b 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -934,6 +934,33 @@ 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);
+
+/** Encodes an EC_KEY private key to an allocated octet string
+ *  \param  key    key to encode
+ *  \param  pbuf   returns pointer to allocated buffer
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+
+size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf);
+
 /********************************************************************/
 /*        de- and encoding functions for SEC1 ECPrivateKey          */
 /********************************************************************/
@@ -1479,8 +1506,10 @@ void ERR_load_EC_strings(void);
 # define EC_F_EC_KEY_GENERATE_KEY                         179
 # define EC_F_EC_KEY_NEW                                  182
 # define EC_F_EC_KEY_NEW_METHOD                           245
+# define EC_F_EC_KEY_OCT2PRIV                             255
 # define EC_F_EC_KEY_PRINT                                180
 # define EC_F_EC_KEY_PRINT_FP                             181
+# define EC_F_EC_KEY_PRIV2OCT                             256
 # define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES    229
 # define EC_F_EC_POINTS_MAKE_AFFINE                       136
 # define EC_F_EC_POINT_ADD                                112
diff --git a/util/libeay.num b/util/libeay.num
index c59581c..7e9db93 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -4795,3 +4795,7 @@ BIO_closesocket                         5189	1_1_0	EXIST::FUNCTION:
 BIO_sock_info                           5190	1_1_0	EXIST::FUNCTION:
 BIO_socket                              5191	1_1_0	EXIST::FUNCTION:
 BIO_listen                              5192	1_1_0	EXIST::FUNCTION:
+EC_KEY_priv2oct                         5193	1_1_0	EXIST::FUNCTION:EC
+EC_KEY_oct2priv                         5194	1_1_0	EXIST::FUNCTION:EC
+ASN1_buf_print                          5195	1_1_0	EXIST::FUNCTION:
+EC_KEY_priv2buf                         5196	1_1_0	EXIST::FUNCTION:EC


More information about the openssl-commits mailing list