Merge pull request #513 from alex/kdf-interface

Begin designing the KDF interfaces. Fixes #511
diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py
index 2654b45..e2542a1 100644
--- a/cryptography/exceptions.py
+++ b/cryptography/exceptions.py
@@ -38,3 +38,7 @@
 
 class InternalError(Exception):
     pass
+
+
+class InvalidKey(Exception):
+    pass
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index 293fcd7..1a27644 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -257,3 +257,19 @@
         """
         The public exponent of the RSA key. Alias for public_exponent.
         """
+
+
+class KeyDerivationFunction(six.with_metaclass(abc.ABCMeta)):
+    @abc.abstractmethod
+    def derive(self, key_material):
+        """
+        Deterministically generates and returns a new key based on the existing
+        key material.
+        """
+
+    @abc.abstractmethod
+    def verify(self, key_material, expected_key):
+        """
+        Checks whether the key generated by the key material matches the
+        expected derived key. Raises an exception if they do not match.
+        """
diff --git a/docs/exceptions.rst b/docs/exceptions.rst
index 1fbd326..1e31e31 100644
--- a/docs/exceptions.rst
+++ b/docs/exceptions.rst
@@ -10,8 +10,8 @@
 
 .. class:: InvalidSignature
 
-    This is raised when the verify method of a hash context does not
-    compare equal.
+    This is raised when the verify method of a hash context's computed digest
+    does not match the expected digest.
 
 
 .. class:: NotYetFinalized
@@ -30,3 +30,9 @@
 
     This is raised when a backend doesn't support the requested algorithm (or
     combination of algorithms).
+
+
+.. class:: InvalidKey
+
+    This is raised when the verify method of a key derivation function's
+    computed key does not match the expected key.
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index bf78e36..2adad91 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -204,4 +204,48 @@
         The public exponent. Alias for :attr:`public_exponent`.
 
 
+Key Derivation Functions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: KeyDerivationFunction
+
+    .. versionadded:: 0.2
+
+    .. method:: derive(key_material)
+
+        :param key_material bytes: The input key material. Depending on what
+                                   key derivation function you are using this
+                                   could be either random material, or a user
+                                   supplied password.
+        :return: The new key.
+        :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+                                                          :meth:`derive` or
+                                                          :meth:`verify` is
+                                                          called more than
+                                                          once.
+
+        This generates and returns a new key from the supplied key material.
+
+    .. method:: verify(key_material, expected_key)
+
+        :param key_material bytes: The input key material. This is the same as
+                                   ``key_material`` in :meth:`derive`.
+        :param expected_key bytes: The expected result of deriving a new key,
+                                   this is the same as the return value of
+                                   :meth:`derive`.
+        :raises cryptography.exceptions.InvalidKey: This is raised when the
+                                                    derived key does not match
+                                                    the expected key.
+        :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+                                                          :meth:`derive` or
+                                                          :meth:`verify` is
+                                                          called more than
+                                                          once.
+
+        This checks whether deriving a new key from the supplied
+        ``key_material`` generates the same key as the ``expected_key``, and
+        raises an exception if they do not match. This can be used for
+        something like checking whether a user's password attempt matches the
+        stored derived key.
+
 .. _`RSA`: http://en.wikipedia.org/wiki/RSA_(cryptosystem)