update EC ASN1 and print routines
authorDr. Stephen Henson <steve@openssl.org>
Mon, 1 Feb 2016 15:46:29 +0000 (15:46 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 5 Feb 2016 00:33:33 +0000 (00:33 +0000)
Update EC ASN.1 and print routines to use EC_KEY_oct2priv and
EC_KEY_priv2oct.

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
crypto/ec/ec_ameth.c
crypto/ec/ec_asn1.c
crypto/ec/ec_err.c
crypto/ec/ec_key.c
include/openssl/ec.h

index 2e43f1d3086bbde0857e1a794a39e8c420c58b68..a0ddb187a255c7e1049f22a1ebbc3240f68f01de 100644 (file)
@@ -383,48 +383,45 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
 {
     unsigned char *buffer = NULL;
     const char *ecstr;
-    size_t buf_len = 0, i;
+    size_t priv_len = 0, pub_len = 0, buf_len = 0;
     int ret = 0, reason = ERR_R_BIO_LIB;
     BIGNUM *pub_key = NULL;
     BN_CTX *ctx = NULL;
     const EC_GROUP *group;
-    const EC_POINT *public_key;
-    const BIGNUM *priv_key;
+    const EC_POINT *public_key = NULL;
 
     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;
-    }
-
     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) {
+            pub_len = EC_POINT_point2oct(group, public_key,
+                                         EC_KEY_get_conv_form(x),
+                                         NULL, 0, NULL);
+            if (pub_len == 0) {
                 reason = ERR_R_EC_LIB;
                 goto err;
             }
-            buf_len = (size_t)BN_num_bytes(pub_key);
+            buf_len = pub_len;
         }
     }
 
-    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 == 2 && EC_KEY_get0_private_key(x) != NULL) {
+        priv_len = EC_KEY_priv2oct(x, NULL, 0);
+        if (priv_len == 0) {
+            reason = ERR_R_EC_LIB;
+            goto err;
+        }
+        if (priv_len > buf_len)
+            buf_len = priv_len;
+    }
 
-    if (ktype > 0) {
-        buf_len += 10;
-        if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
+    if (buf_len != 0) {
+        buffer = OPENSSL_malloc(buf_len);
+        if (buffer == NULL) {
             reason = ERR_R_MALLOC_FAILURE;
             goto err;
         }
@@ -442,12 +439,26 @@ 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 (priv_len != 0) {
+        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
+            goto err;
+        if (EC_KEY_priv2oct(x, buffer, priv_len) == 0)
+            goto err;
+        if (ASN1_buf_print(bp, buffer, priv_len, off + 4) == 0)
+            goto err;
+    }
+
+    if (pub_len != 0) {
+        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
+            goto err;
+        if (EC_POINT_point2oct(group, public_key,
+                               EC_KEY_get_conv_form(x),
+                               buffer, pub_len, NULL) == 0)
+            goto err;
+        if (ASN1_buf_print(bp, buffer, pub_len, off + 4) == 0)
+            goto err;
+    }
+
     if (!ECPKParameters_print(bp, group, off))
         goto err;
     ret = 1;
@@ -456,8 +467,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
         ECerr(EC_F_DO_EC_KEY_PRINT, reason);
     BN_free(pub_key);
     BN_CTX_free(ctx);
-    OPENSSL_free(buffer);
-    return (ret);
+    OPENSSL_clear_free(buffer, buf_len);
+    return ret;
 }
 
 static int eckey_param_decode(EVP_PKEY *pkey,
index 842f9c31df2549ae6a7be66db32c96dde66be29c..92bfe06ec56ab5d71436d61a03a4c315c4bfd633 100644 (file)
@@ -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;
@@ -1085,10 +1076,10 @@ 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;
+    size_t buf_len = 0, tmp_len;
     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,14 +1092,10 @@ 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 */
+    buf_len = EC_KEY_priv2oct(a, NULL, 0);
 
-    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);
+    if (buf_len == 0) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
         goto err;
     }
 
@@ -1118,15 +1105,11 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
         goto err;
     }
 
-    if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) {
-        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
+    if (EC_KEY_priv2oct(a, buffer, buf_len) == 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;
index 4811fa25dc0ff074ac111e282684d225d7afe6ea..b4edc212f5b9ccfaabd47a7220f6feda12cbcdda 100644 (file)
@@ -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"},
index 9fb6a6af135027cd36223fe806fc4e5912dbbb54..13324982d5768fe5d95382c395ffd83c43ee0567 100644 (file)
@@ -568,12 +568,12 @@ size_t EC_KEY_priv2oct(const EC_KEY *eckey, unsigned char *buf, size_t len)
     /* 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);
+        ECerr(EC_F_EC_KEY_PRIV2OCT, 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);
+        ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_BN_LIB);
         return 0;
     }
 
@@ -591,12 +591,12 @@ int EC_KEY_oct2priv(EC_KEY *eckey, unsigned char *buf, size_t len)
     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);
+        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_D2I_ECPRIVATEKEY, ERR_R_BN_LIB);
+        ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_BN_LIB);
         return 0;
     }
     return 1;
index 967edf3538f15aee4be4d9a53177961f65eac7d5..7fed45f7e60d308db5f3ba983b35b7450bb5adaa 100644 (file)
@@ -1499,8 +1499,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