ECDSA backend
diff --git a/tests/conftest.py b/tests/conftest.py
index b1326dc..af14638 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -17,8 +17,8 @@
 
 from cryptography.hazmat.backends import _available_backends
 from cryptography.hazmat.backends.interfaces import (
-    CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
-    PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend,
+    CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend,
+    HashBackend, PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend,
     TraditionalOpenSSLSerializationBackend
 )
 from .utils import check_backend_support, check_for_iface, select_backends
@@ -46,11 +46,8 @@
         TraditionalOpenSSLSerializationBackend,
         item
     )
-    check_for_iface(
-        "pkcs8_serialization",
-        PKCS8SerializationBackend,
-        item
-    )
+    check_for_iface("pkcs8_serialization", PKCS8SerializationBackend, item)
+    check_for_iface("elliptic", EllipticCurveBackend, item)
     check_backend_support(item)
 
 
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index bfcdf14..aa2122f 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -19,7 +19,9 @@
 
 from cryptography import utils
 from cryptography.exceptions import InternalError, _Reasons
-from cryptography.hazmat.backends.openssl.backend import Backend, backend
+from cryptography.hazmat.backends.openssl.backend import (
+    Backend, backend
+)
 from cryptography.hazmat.primitives import hashes, interfaces
 from cryptography.hazmat.primitives.asymmetric import dsa, padding, rsa
 from cryptography.hazmat.primitives.ciphers import Cipher
@@ -445,3 +447,22 @@
         key = pretend.stub(type="unsupported")
         with raises_unsupported_algorithm(None):
             backend._evp_pkey_to_private_key(key)
+
+
+class TestOpenSSLNoEllipticCurve(object):
+    def test_elliptic_curve_supported(self, monkeypatch):
+        monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0)
+
+        assert backend.elliptic_curve_supported(None) is False
+
+    def test_elliptic_curve_signature_algorithm_supported(self, monkeypatch):
+        monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0)
+
+        assert backend.elliptic_curve_signature_algorithm_supported(
+            None, None
+        ) is False
+
+    def test_supported_curves(self, monkeypatch):
+        monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0)
+
+        assert backend._supported_curves() == []
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 53985fe..1879f4f 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -14,66 +14,286 @@
 
 from __future__ import absolute_import, division, print_function
 
+import itertools
+import os
+
 import pytest
 
-from cryptography import utils
-from cryptography.hazmat.primitives import interfaces
+from cryptography import exceptions, utils
+from cryptography.hazmat.primitives import hashes, interfaces
 from cryptography.hazmat.primitives.asymmetric import ec
 
+from ...utils import (
+    der_encode_dsa_signature, load_fips_ecdsa_key_pair_vectors,
+    load_fips_ecdsa_signing_vectors, load_vectors_from_file,
+    raises_unsupported_algorithm
+)
+
+_CURVE_TYPES = {
+    "secp192r1": ec.SECP192R1,
+    "secp224r1": ec.SECP224R1,
+    "secp256r1": ec.SECP256R1,
+    "secp384r1": ec.SECP384R1,
+    "secp521r1": ec.SECP521R1,
+
+    "sect163k1": ec.SECT163K1,
+    "sect233k1": ec.SECT233K1,
+    "sect283k1": ec.SECT283K1,
+    "sect409k1": ec.SECT409K1,
+    "sect571k1": ec.SECT571K1,
+
+    "sect163r2": ec.SECT163R2,
+    "sect233r1": ec.SECT233R1,
+    "sect283r1": ec.SECT283R1,
+    "sect409r1": ec.SECT409R1,
+    "sect571r1": ec.SECT571R1,
+}
+
+_HASH_TYPES = {
+    "SHA-1": hashes.SHA1,
+    "SHA-224": hashes.SHA224,
+    "SHA-256": hashes.SHA256,
+    "SHA-384": hashes.SHA384,
+    "SHA-512": hashes.SHA512,
+}
+
+
+def _skip_ecdsa_vector(backend, curve_type, hash_type):
+    if not backend.elliptic_curve_signature_algorithm_supported(
+        ec.ECDSA(hash_type()),
+        curve_type()
+    ):
+        pytest.skip(
+            "ECDSA not supported with this hash {0} and curve {1}".format(
+                hash_type().name, curve_type().name
+            )
+        )
+
 
 @utils.register_interface(interfaces.EllipticCurve)
 class DummyCurve(object):
     name = "dummy-curve"
+    key_size = 1
 
 
-class TestECC(object):
-    def test_ec_numbers(self):
-        numbers = ec.EllipticCurvePrivateNumbers(
-            1,
+@utils.register_interface(interfaces.EllipticCurveSignatureAlgorithm)
+class DummySignatureAlgorithm(object):
+    pass
+
+
+def test_ec_numbers():
+    numbers = ec.EllipticCurvePrivateNumbers(
+        1,
+        ec.EllipticCurvePublicNumbers(
+            2, 3, DummyCurve()
+        )
+    )
+
+    assert numbers.private_value == 1
+    assert numbers.public_numbers.x == 2
+    assert numbers.public_numbers.y == 3
+    assert isinstance(numbers.public_numbers.curve, DummyCurve)
+
+    with pytest.raises(TypeError):
+        ec.EllipticCurvePrivateNumbers(
+            None,
             ec.EllipticCurvePublicNumbers(
                 2, 3, DummyCurve()
             )
         )
 
-        assert numbers.private_value == 1
-        assert numbers.public_numbers.x == 2
-        assert numbers.public_numbers.y == 3
-        assert isinstance(numbers.public_numbers.curve, DummyCurve)
+    with pytest.raises(TypeError):
+        ec.EllipticCurvePrivateNumbers(
+            1,
+            ec.EllipticCurvePublicNumbers(
+                None, 3, DummyCurve()
+            )
+        )
 
-        with pytest.raises(TypeError):
-            ec.EllipticCurvePrivateNumbers(
-                None,
-                ec.EllipticCurvePublicNumbers(
-                    2, 3, DummyCurve()
+    with pytest.raises(TypeError):
+        ec.EllipticCurvePrivateNumbers(
+            1,
+            ec.EllipticCurvePublicNumbers(
+                2, None, DummyCurve()
+            )
+        )
+
+    with pytest.raises(TypeError):
+        ec.EllipticCurvePrivateNumbers(
+            1,
+            ec.EllipticCurvePublicNumbers(
+                2, 3, None
+            )
+        )
+
+    with pytest.raises(TypeError):
+        ec.EllipticCurvePrivateNumbers(
+            1,
+            None
+        )
+
+
+@pytest.mark.elliptic
+class TestECDSAVectors(object):
+    @pytest.mark.parametrize(
+        ("vector", "hash_type"),
+        list(itertools.product(
+            load_vectors_from_file(
+                os.path.join(
+                    "asymmetric", "ECDSA", "FIPS_186-3", "KeyPair.rsp"),
+                load_fips_ecdsa_key_pair_vectors
+            ),
+            _HASH_TYPES.values()
+        ))
+    )
+    def test_signing_with_example_keys(self, backend, vector, hash_type):
+        curve_type = _CURVE_TYPES[vector['curve']]
+
+        _skip_ecdsa_vector(backend, curve_type, hash_type)
+
+        key = ec.EllipticCurvePrivateNumbers(
+            vector['d'],
+            ec.EllipticCurvePublicNumbers(
+                vector['x'],
+                vector['y'],
+                curve_type()
+            )
+        ).private_key(backend)
+        assert key
+
+        pkey = key.public_key()
+        assert pkey
+
+        signer = key.signer(ec.ECDSA(hash_type()))
+        signer.update(b"YELLOW SUBMARINE")
+        signature = signer.finalize()
+
+        verifier = pkey.verifier(signature, ec.ECDSA(hash_type()))
+        verifier.update(b"YELLOW SUBMARINE")
+        verifier.verify()
+
+    @pytest.mark.parametrize(
+        "curve", _CURVE_TYPES.values()
+    )
+    def test_generate_vector_curves(self, backend, curve):
+        if not backend.elliptic_curve_supported(curve()):
+            pytest.skip(
+                "Curve {0} is not supported by this backend {1}".format(
+                    curve().name, backend
                 )
             )
 
-        with pytest.raises(TypeError):
-            ec.EllipticCurvePrivateNumbers(
-                1,
-                ec.EllipticCurvePublicNumbers(
-                    None, 3, DummyCurve()
+        key = ec.generate_private_key(curve(), backend)
+        assert key
+        assert isinstance(key.curve, curve)
+        assert key.curve.key_size
+
+        pkey = key.public_key()
+        assert pkey
+        assert isinstance(pkey.curve, curve)
+        assert key.curve.key_size == pkey.curve.key_size
+
+    def test_generate_unknown_curve(self, backend):
+        with raises_unsupported_algorithm(
+            exceptions._Reasons.UNSUPPORTED_ELLIPTIC_CURVE
+        ):
+            ec.generate_private_key(DummyCurve(), backend)
+
+        assert backend.elliptic_curve_signature_algorithm_supported(
+            ec.ECDSA(hashes.SHA256()),
+            DummyCurve()
+        ) is False
+
+    def test_unknown_signature_algoritm(self, backend):
+        if not backend.elliptic_curve_supported(ec.SECP192R1()):
+            pytest.skip(
+                "Curve secp192r1 is not supported by this backend {0}".format(
+                    backend
                 )
             )
 
-        with pytest.raises(TypeError):
-            ec.EllipticCurvePrivateNumbers(
-                1,
-                ec.EllipticCurvePublicNumbers(
-                    2, None, DummyCurve()
-                )
-            )
+        key = ec.generate_private_key(ec.SECP192R1(), backend)
 
-        with pytest.raises(TypeError):
-            ec.EllipticCurvePrivateNumbers(
-                1,
-                ec.EllipticCurvePublicNumbers(
-                    2, 3, None
-                )
-            )
+        with raises_unsupported_algorithm(
+            exceptions._Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+        ):
+            key.signer(DummySignatureAlgorithm())
 
-        with pytest.raises(TypeError):
-            ec.EllipticCurvePrivateNumbers(
-                1,
-                None
-            )
+        with raises_unsupported_algorithm(
+            exceptions._Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+        ):
+            key.public_key().verifier(b"", DummySignatureAlgorithm())
+
+        assert backend.elliptic_curve_signature_algorithm_supported(
+            DummySignatureAlgorithm(),
+            ec.SECP192R1()
+        ) is False
+
+    @pytest.mark.parametrize(
+        "vector",
+        load_vectors_from_file(
+            os.path.join(
+                "asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt"),
+            load_fips_ecdsa_signing_vectors
+        )
+    )
+    def test_signatures(self, backend, vector):
+        hash_type = _HASH_TYPES[vector['digest_algorithm']]
+        curve_type = _CURVE_TYPES[vector['curve']]
+
+        _skip_ecdsa_vector(backend, curve_type, hash_type)
+
+        key = ec.EllipticCurvePublicNumbers(
+            vector['x'],
+            vector['y'],
+            curve_type()
+        ).public_key(backend)
+
+        signature = der_encode_dsa_signature(
+            vector['r'],
+            vector['s']
+        )
+
+        verifier = key.verifier(
+            signature,
+            ec.ECDSA(hash_type())
+        )
+        verifier.update(vector['message'])
+        assert verifier.verify()
+
+    @pytest.mark.parametrize(
+        "vector",
+        load_vectors_from_file(
+            os.path.join(
+                "asymmetric", "ECDSA", "FIPS_186-3", "SigVer.rsp"),
+            load_fips_ecdsa_signing_vectors
+        )
+    )
+    def test_signature_failures(self, backend, vector):
+        hash_type = _HASH_TYPES[vector['digest_algorithm']]
+        curve_type = _CURVE_TYPES[vector['curve']]
+
+        _skip_ecdsa_vector(backend, curve_type, hash_type)
+
+        key = ec.EllipticCurvePublicNumbers(
+            vector['x'],
+            vector['y'],
+            curve_type()
+        ).public_key(backend)
+
+        signature = der_encode_dsa_signature(
+            vector['r'],
+            vector['s']
+        )
+
+        verifier = key.verifier(
+            signature,
+            ec.ECDSA(hash_type())
+        )
+        verifier.update(vector['message'])
+
+        if vector["fail"] is True:
+            with pytest.raises(exceptions.InvalidSignature):
+                verifier.verify()
+        else:
+            verifier.verify()