[gnutls] enable ECC NIST Suite B curves

Tomáš Mráz tmraz at fedoraproject.org
Wed Oct 16 20:39:54 UTC 2013


commit aaa40d934c8c4dac68b00342730096a030477228
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date:   Wed Oct 16 22:26:28 2013 +0200

    enable ECC NIST Suite B curves
    
    Conflicts:
    	gnutls.spec

 .gitignore                 |    1 +
 ecc.c                      |  301 ++++++++++++++++++++
 gnutls-3.1.11-noecc.patch  |  663 --------------------------------------------
 gnutls-3.1.11-nosrp.patch  |   12 +
 gnutls-3.1.11-suiteb.patch |  119 ++++++++
 gnutls.spec                |   19 +-
 hobble-gnutls              |    8 +-
 sources                    |    2 +-
 8 files changed, 448 insertions(+), 677 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 082994c..2bed46e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ gnutls-2.10.1-nosrp.tar.bz2
 /gnutls-3.1.10-hobbled.tar.xz
 /gnutls-3.1.11-hobbled.tar.xz
 /gnutls-3.1.13-hobbled.tar.xz
+/gnutls-3.1.13-hobbled-el.tar.xz
diff --git a/ecc.c b/ecc.c
new file mode 100644
index 0000000..7ca1776
--- /dev/null
+++ b/ecc.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <gnutls_int.h>
+#include <algorithms.h>
+#include <gnutls_errors.h>
+#include <x509/common.h>
+
+
+/* Supported ECC curves
+ */
+
+static const gnutls_ecc_curve_entry_st ecc_curves[] = {
+  {
+    .name = "SECP256R1", 
+    .oid = "1.2.840.10045.3.1.7",
+    .id = GNUTLS_ECC_CURVE_SECP256R1,
+    .tls_id = 23,
+    .size = 32,
+    .prime = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+    .A = "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+    .B = "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+    .order = "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+    .Gx = "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+    .Gy = "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+  },
+  {
+    .name = "SECP384R1",
+    .oid = "1.3.132.0.34",
+    .id = GNUTLS_ECC_CURVE_SECP384R1,
+    .tls_id = 24,
+    .size = 48,
+    .prime = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+    .A = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+    .B = "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+    .order = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+    .Gx = "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+    .Gy = "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"
+  },
+  {0, 0, 0}
+};
+
+#define GNUTLS_ECC_CURVE_LOOP(b) \
+	{ const gnutls_ecc_curve_entry_st *p; \
+                for(p = ecc_curves; p->name != NULL; p++) { b ; } }
+
+
+/* Returns the TLS id of the given curve
+ */
+int
+_gnutls_tls_id_to_ecc_curve (int num)
+{
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
+
+  GNUTLS_ECC_CURVE_LOOP (
+  if (p->tls_id == num) 
+    {
+      ret = p->id;
+      break;
+    }
+  );
+  
+  return ret;
+}
+
+/**
+ * gnutls_ecc_curve_list:
+ *
+ * Get the list of supported elliptic curves.
+ *
+ * This function is not thread safe.
+ *
+ * Returns: Return a (0)-terminated list of #gnutls_ecc_curve_t
+ *   integers indicating the available curves.
+ **/
+const gnutls_ecc_curve_t *
+gnutls_ecc_curve_list (void)
+{
+static gnutls_ecc_curve_t supported_curves[MAX_ALGOS] = { 0 };
+
+  if (supported_curves[0] == 0)
+    {
+      int i = 0;
+
+      GNUTLS_ECC_CURVE_LOOP ( 
+        supported_curves[i++]=p->id;
+      );
+      supported_curves[i++]=0;
+    }
+
+  return supported_curves;
+}
+
+/* Maps numbers to TLS NamedCurve IDs (RFC4492).
+ * Returns a negative number on error.
+ */
+int
+_gnutls_ecc_curve_get_tls_id (gnutls_ecc_curve_t supported_ecc)
+{
+  int ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
+
+  GNUTLS_ECC_CURVE_LOOP (
+  if (p->id == supported_ecc) 
+    {
+      ret = p->tls_id;
+      break;
+    }
+  );
+  
+  return ret;
+}
+
+/*-
+ * _gnutls_oid_to_ecc_curve:
+ * @oid: is a curve's OID
+ *
+ * Returns: return a #gnutls_ecc_curve_t value corresponding to
+ *   the specified OID, or %GNUTLS_ECC_CURVE_INVALID on error.
+ -*/
+gnutls_ecc_curve_t _gnutls_oid_to_ecc_curve (const char* oid)
+{
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
+
+  GNUTLS_ECC_CURVE_LOOP (
+  if (strcasecmp (p->oid, oid) == 0) 
+    {
+      ret = p->id;
+      break;
+    }
+  );
+
+  return ret;
+}
+
+/*-
+ * _gnutls_ecc_curve_get_id:
+ * @name: is a curve name
+ *
+ * The names are compared in a case insensitive way.
+ *
+ * Returns: return a #gnutls_ecc_curve_t value corresponding to
+ *   the specified curve, or %GNUTLS_ECC_CURVE_INVALID on error.
+ -*/
+gnutls_ecc_curve_t
+_gnutls_ecc_curve_get_id (const char *name)
+{
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID;
+
+  GNUTLS_ECC_CURVE_LOOP (
+  if (strcasecmp (p->name, name) == 0) 
+    {
+      ret = p->id;
+      break;
+    }
+  );
+
+  return ret;
+}
+
+/*-
+ * _gnutls_ecc_bits_to_curve:
+ * @bits: is a security parameter in bits
+ *
+ * Returns: return a #gnutls_ecc_curve_t value corresponding to
+ *   the specified bit length, or %GNUTLS_ECC_CURVE_INVALID on error.
+ -*/
+gnutls_ecc_curve_t
+_gnutls_ecc_bits_to_curve (int bits)
+{
+  gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_SECP224R1;
+
+  GNUTLS_ECC_CURVE_LOOP (
+    if (8*p->size >= bits)
+      {
+        ret = p->id;
+        break;
+      }
+  );
+
+  return ret;
+}
+
+/**
+ * gnutls_ecc_curve_get_name:
+ * @curve: is an ECC curve
+ *
+ * Convert a #gnutls_ecc_curve_t value to a string.
+ *
+ * Returns: a string that contains the name of the specified
+ *   curve or %NULL.
+ *
+ * Since: 3.0
+ **/
+const char *
+gnutls_ecc_curve_get_name (gnutls_ecc_curve_t curve)
+{
+  const char *ret = NULL;
+
+  GNUTLS_ECC_CURVE_LOOP(
+    if (p->id == curve)
+      {
+        ret = p->name;
+        break;
+      }
+  );
+
+  return ret;
+}
+
+/*-
+ * _gnutls_ecc_curve_get_oid:
+ * @curve: is an ECC curve
+ *
+ * Convert a #gnutls_ecc_curve_t value to a string.
+ *
+ * Returns: a string that contains the name of the specified
+ *   curve or %NULL.
+ -*/
+const char *
+_gnutls_ecc_curve_get_oid (gnutls_ecc_curve_t curve)
+{
+  const char *ret = NULL;
+
+  GNUTLS_ECC_CURVE_LOOP(
+    if (p->id == curve)
+      {
+        ret = p->oid;
+        break;
+      }
+  );
+
+  return ret;
+}
+
+/*-
+ * _gnutls_ecc_curve_get_params:
+ * @curve: is an ECC curve
+ *
+ * Returns the information on a curve.
+ *
+ * Returns: a pointer to #gnutls_ecc_curve_entry_st or %NULL.
+ -*/
+const gnutls_ecc_curve_entry_st *
+_gnutls_ecc_curve_get_params (gnutls_ecc_curve_t curve)
+{
+  const gnutls_ecc_curve_entry_st *ret = NULL;
+
+  GNUTLS_ECC_CURVE_LOOP(
+    if (p->id == curve)
+      {
+        ret = p;
+        break;
+      }
+  );
+
+  return ret;
+}
+
+/**
+ * gnutls_ecc_curve_get_size:
+ * @curve: is an ECC curve
+ *
+ * Returns the size in bytes of the curve.
+ *
+ * Returns: a the size or (0).
+ *
+ * Since: 3.0
+ **/
+int gnutls_ecc_curve_get_size (gnutls_ecc_curve_t curve)
+{
+  int ret = 0;
+
+  GNUTLS_ECC_CURVE_LOOP(
+    if (p->id == curve)
+      {
+        ret = p->size;
+        break;
+      }
+  );
+
+  return ret;
+}
diff --git a/gnutls-3.1.11-nosrp.patch b/gnutls-3.1.11-nosrp.patch
new file mode 100644
index 0000000..29227c0
--- /dev/null
+++ b/gnutls-3.1.11-nosrp.patch
@@ -0,0 +1,12 @@
+diff -up gnutls-3.1.10/tests/srp/mini-srp.c.noecc gnutls-3.1.10/tests/srp/mini-srp.c
+--- gnutls-3.1.10/tests/srp/mini-srp.c.noecc	2013-03-21 21:42:28.000000000 +0100
++++ gnutls-3.1.10/tests/srp/mini-srp.c	2013-03-25 13:42:20.753422209 +0100
+@@ -27,7 +27,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+-#if defined(_WIN32)
++#if defined(_WIN32) || !defined(ENABLE_SRP)
+ 
+ int main()
+ {
diff --git a/gnutls-3.1.11-suiteb.patch b/gnutls-3.1.11-suiteb.patch
new file mode 100644
index 0000000..c4dd390
--- /dev/null
+++ b/gnutls-3.1.11-suiteb.patch
@@ -0,0 +1,119 @@
+diff -up gnutls-3.1.11/lib/gnutls_ecc.c.suiteb gnutls-3.1.11/lib/gnutls_ecc.c
+--- gnutls-3.1.11/lib/gnutls_ecc.c.suiteb	2013-04-27 10:04:48.000000000 +0200
++++ gnutls-3.1.11/lib/gnutls_ecc.c	2013-05-23 10:08:45.331883555 +0200
+@@ -129,6 +129,12 @@ int ret;
+       goto cleanup;
+     }
+   params->params_nr++;
++
++  if (_gnutls_mpi_get_nbits(params->params[ECC_PRIME]) < 256)
++    {
++      ret = gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
++      goto cleanup;
++    }
+   
+   val_size = sizeof(val);
+   ret = _gnutls_hex2bin(st->order, strlen(st->order), val, &val_size);
+diff -up gnutls-3.1.11/lib/nettle/ecc_mulmod_cached.c.suiteb gnutls-3.1.11/lib/nettle/ecc_mulmod_cached.c
+--- gnutls-3.1.11/lib/nettle/ecc_mulmod_cached.c.suiteb	2013-04-27 10:04:48.000000000 +0200
++++ gnutls-3.1.11/lib/nettle/ecc_mulmod_cached.c	2013-05-23 10:24:56.575967312 +0200
+@@ -42,6 +42,7 @@ typedef struct
+ 
+ /* global cache */
+ static gnutls_ecc_curve_cache_entry_t *ecc_wmnaf_cache = NULL;
++static gnutls_ecc_curve_cache_entry_t *ecc_wmnaf_cache_last = NULL;
+ 
+ /* free single cache entry */
+ static void
+@@ -63,9 +64,10 @@ ecc_wmnaf_cache_free (void)
+   gnutls_ecc_curve_cache_entry_t *p = ecc_wmnaf_cache;
+   if (p)
+     {
+-      for (; p->id != GNUTLS_ECC_CURVE_INVALID; ++p)
++      for (; p <= ecc_wmnaf_cache_last; ++p)
+         {
+-          _ecc_wmnaf_cache_entry_free (p);
++          if (p->id != GNUTLS_ECC_CURVE_INVALID)
++            _ecc_wmnaf_cache_entry_free (p);
+         }
+ 
+       free (ecc_wmnaf_cache);
+@@ -198,7 +200,7 @@ ecc_wmnaf_cache_init (void)
+   const gnutls_ecc_curve_t *p;
+ 
+   ret = (gnutls_ecc_curve_cache_entry_t *)
+-    malloc (MAX_ALGOS * sizeof (gnutls_ecc_curve_cache_entry_t));
++    calloc (MAX_ALGOS, sizeof (gnutls_ecc_curve_cache_entry_t));
+   if (ret == NULL)
+     return GNUTLS_E_MEMORY_ERROR;
+ 
+@@ -207,12 +209,16 @@ ecc_wmnaf_cache_init (void)
+ 
+   for (j = 0; *p; ++p, ++j)
+     {
+-      if ((err = _ecc_wmnaf_cache_entry_init (ret + *p - 1, *p)) != 0)
++      gnutls_ecc_curve_cache_entry_t *entry;
++
++      entry = ret + *p - 1;
++      if ((err = _ecc_wmnaf_cache_entry_init (entry, *p)) != 0)
+         goto done;
++      if (ecc_wmnaf_cache_last < entry)
++        ecc_wmnaf_cache_last = entry;
+     }
+ 
+-  /* nullify last cache entry id */
+-  ret[j].id = GNUTLS_ECC_CURVE_INVALID;
++  /* no need to nullify last cache entry id, done by calloc */
+ 
+   err = GNUTLS_E_SUCCESS;
+ 
+@@ -223,7 +229,8 @@ done:
+       int i;
+       for (i = 0; i < j; ++i)
+         {
+-          _ecc_wmnaf_cache_entry_free (ret + i);
++          --p;
++          _ecc_wmnaf_cache_entry_free (ret + *p - 1);
+         }
+ 
+       free (ret);
+@@ -445,9 +452,11 @@ ecc_mulmod_cached_lookup (mpz_t k, ecc_p
+   if (k == NULL || G == NULL || R == NULL || modulus == NULL)
+     return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
+ 
+-  for (i = 0; (id = ecc_wmnaf_cache[i].id); ++i)
++  for (i = 0; ecc_wmnaf_cache + i <= ecc_wmnaf_cache_last; ++i)
+     {
+-      if (!(mpz_cmp (G->x, ecc_wmnaf_cache[i].pos[0]->x)) &&
++      id = ecc_wmnaf_cache[i].id;
++      if (id &&
++          !(mpz_cmp (G->x, ecc_wmnaf_cache[i].pos[0]->x)) &&
+           !(mpz_cmp (G->y, ecc_wmnaf_cache[i].pos[0]->y)))
+         {
+           break;
+diff -up gnutls-3.1.11/tests/mini-xssl.c.suiteb gnutls-3.1.11/tests/mini-xssl.c
+--- gnutls-3.1.11/tests/mini-xssl.c.suiteb	2013-05-10 10:10:27.000000000 +0200
++++ gnutls-3.1.11/tests/mini-xssl.c	2013-05-23 11:58:22.670298910 +0200
+@@ -27,7 +27,8 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+-#if defined(_WIN32)
++/* uses unsupported curves */
++#if 1
+ 
+ int main()
+ {
+diff -up gnutls-3.1.11/tests/pkcs12_simple.c.suiteb gnutls-3.1.11/tests/pkcs12_simple.c
+--- gnutls-3.1.11/tests/pkcs12_simple.c.suiteb	2013-05-10 10:10:27.000000000 +0200
++++ gnutls-3.1.11/tests/pkcs12_simple.c	2013-05-23 11:57:59.776799848 +0200
+@@ -50,6 +50,9 @@ doit (void)
+   gnutls_x509_privkey_t pkey;
+   int ret;
+ 
++  /* uses unsupported curves */
++  exit(77);
++
+   ret = global_init ();
+   if (ret < 0)
+     fail ("global_init failed %d\n", ret);
diff --git a/gnutls.spec b/gnutls.spec
index 6ce83b1..ceb9e0d 100644
--- a/gnutls.spec
+++ b/gnutls.spec
@@ -3,7 +3,7 @@
 Summary: A TLS protocol implementation
 Name: gnutls
 Version: 3.1.13
-Release: 2%{?dist}
+Release: 3%{?dist}
 # The libraries are LGPLv2.1+, utilities are GPLv3+, however
 # the bundled gnulib is LGPLv3+
 License: GPLv3+ and LGPLv2+ and LGPLv3+
@@ -22,16 +22,17 @@ URL: http://www.gnutls.org/
 #Source0: ftp://ftp.gnutls.org/gcrypt/gnutls/%{name}-%{version}.tar.xz
 #Source1: ftp://ftp.gnutls.org/gcrypt/gnutls/%{name}-%{version}.tar.xz.sig
 # XXX patent tainted code removed.
-Source0: %{name}-%{version}-hobbled.tar.xz
+Source0: %{name}-%{version}-hobbled-el.tar.xz
 Source1: libgnutls-config
 Source2: hobble-gnutls
+Source3: ecc.c
 Patch1: gnutls-3.1.7-rpath.patch
 # Use only FIPS approved ciphers in the FIPS mode
 Patch7: gnutls-2.12.21-fips-algorithms.patch
-# Make ECC optional as it is now hobbled
-Patch8: gnutls-3.1.11-noecc.patch
+Patch8: gnutls-3.1.11-nosrp.patch
 # Use random port in some tests to avoid conflicts during simultaneous builds on the same machine
 Patch9: gnutls-3.1.10-tests-rndport.patch
+Patch10: gnutls-3.1.11-suiteb.patch
 
 # Wildcard bundling exception https://fedorahosted.org/fpc/ticket/174
 Provides: bundled(gnulib) = 20130424
@@ -124,13 +125,15 @@ This package contains Guile bindings for the library.
 # This patch is not applicable as we use nettle now but some parts will be
 # later reused.
 #%patch7 -p1 -b .fips
-%patch8 -p1 -b .noecc
+%patch8 -p1 -b .nosrp
 %patch9 -p1 -b .rndport
+%patch10 -p1 -b .suiteb
 
 %{SOURCE2} -e
 
+cp -f %{SOURCE3} lib/algorithms
+
 %build
-autoreconf -f
 
 export LDFLAGS="-Wl,--no-add-needed"
 
@@ -139,7 +142,6 @@ export LDFLAGS="-Wl,--no-add-needed"
            --disable-static \
            --disable-openssl-compatibility \
            --disable-srp-authentication \
-           --disable-ecdhe \
 %if %{with guile}
            --enable-guile \
 %ifarch %{arm}
@@ -255,6 +257,9 @@ fi
 %endif
 
 %changelog
+* Wed Oct 16 2013 Tomáš Mráz <tmraz at redhat.com> 3.1.13-3
+- enable ECC NIST Suite B curves
+
 * Sat Aug 03 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 3.1.13-2
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
 
diff --git a/hobble-gnutls b/hobble-gnutls
index f33cfb5..8b9633d 100755
--- a/hobble-gnutls
+++ b/hobble-gnutls
@@ -14,10 +14,6 @@ for f in auth_srp_sb64.c auth_srp_passwd.c auth_srp_rsa.c \
 done
 
 # ECC
-for f in ecc_free.c ecc_make_key.c ecc_shared_secret.c \
-    ecc_map.c ecc_mulmod.c ecc_mulmod_cached.c \
-    ecc_points.c ecc_projective_dbl_point_3.c ecc_projective_isneutral.c \
-    ecc_projective_check_point.c ecc_projective_negate_point.c \
-    ecc_projective_add_point_ng.c ecc_sign_hash.c ecc_verify_hash.c ; do
-    eval "$CMD lib/nettle/$f"
+for f in ecc.c ; do
+    eval "$CMD lib/algorithms/$f"
 done
diff --git a/sources b/sources
index 3f61b3c..0e3c477 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-4b87223377a4b7f2974ff99b997732ef  gnutls-3.1.13-hobbled.tar.xz
+17d3ed05939acbe443bf22a0d5998e63  gnutls-3.1.13-hobbled-el.tar.xz


More information about the scm-commits mailing list