Merge branch 'master' into common-crypto-backend

* master: (24 commits)
  Expose the innards of DH and DSA
  More bindings for asymmetric stuff
  Tell cffi these opaque types are pointers.
  rename variable to be less confusing and terrible
  Document when the common crypto bindings were added
  Expose a name needed for ECDHE -- the NIDs are always available
  Expose the nids for the various eliptical curve things. I don't understand what these mean.
  Specify the epub theme to fix the epub build on RTD.
  Added forgotten decl
  reversed
  Allow these to not be defined because lololol fedora/centos
  add conditional ERR_remove_thread_state. PyOpenSSL uses this
  Don't require sphinx spelling to be installed, for readthedocs benefit
  This is also a requirement
  oops
  Start binding some stuff for ECDHE in pyOpenSSL.
  check if openssl is installed via homebrew on osx. install if not
  Verify the tag len for GCM
  remove comment that's no longer needed
  Make just one call to ffi.cdef for most of the definitions
  ...
diff --git a/cryptography/hazmat/backends/__init__.py b/cryptography/hazmat/backends/__init__.py
index 215aa4d..cb1fee9 100644
--- a/cryptography/hazmat/backends/__init__.py
+++ b/cryptography/hazmat/backends/__init__.py
@@ -12,11 +12,15 @@
 # limitations under the License.
 
 from cryptography.hazmat.backends import openssl
+from cryptography.hazmat.bindings.commoncrypto.binding import (
+    Binding as CCBinding
+)
 
+_ALL_BACKENDS = [openssl.backend]
 
-_ALL_BACKENDS = [
-    openssl.backend
-]
+if CCBinding.is_available():
+    from cryptography.hazmat.backends import commoncrypto
+    _ALL_BACKENDS.append(commoncrypto.backend)
 
 
 def default_backend():
diff --git a/cryptography/hazmat/backends/commoncrypto/__init__.py b/cryptography/hazmat/backends/commoncrypto/__init__.py
new file mode 100644
index 0000000..64a1c01
--- /dev/null
+++ b/cryptography/hazmat/backends/commoncrypto/__init__.py
@@ -0,0 +1,17 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from cryptography.hazmat.backends.commoncrypto.backend import backend
+
+
+__all__ = ["backend"]
diff --git a/cryptography/hazmat/backends/commoncrypto/backend.py b/cryptography/hazmat/backends/commoncrypto/backend.py
new file mode 100644
index 0000000..efbd6ba
--- /dev/null
+++ b/cryptography/hazmat/backends/commoncrypto/backend.py
@@ -0,0 +1,128 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+from collections import namedtuple
+
+from cryptography import utils
+from cryptography.exceptions import UnsupportedAlgorithm
+from cryptography.hazmat.backends.interfaces import (
+    HashBackend,
+)
+from cryptography.hazmat.bindings.commoncrypto.binding import Binding
+from cryptography.hazmat.primitives import interfaces
+
+
+@utils.register_interface(HashBackend)
+class Backend(object):
+    """
+    CommonCrypto API wrapper.
+    """
+    hashtuple = namedtuple("HashClass", ["struct", "init", "update", "final"])
+
+    def __init__(self):
+        self._binding = Binding()
+        self._ffi = self._binding.ffi
+        self._lib = self._binding.lib
+
+        self.hash_methods = {
+            b"md5": self.hashtuple(
+                "CC_MD5_CTX *", self._lib.CC_MD5_Init,
+                self._lib.CC_MD5_Update, self._lib.CC_MD5_Final
+            ),
+            b"sha1": self.hashtuple(
+                "CC_SHA1_CTX *", self._lib.CC_SHA1_Init,
+                self._lib.CC_SHA1_Update, self._lib.CC_SHA1_Final
+            ),
+            b"sha224": self.hashtuple(
+                "CC_SHA256_CTX *", self._lib.CC_SHA224_Init,
+                self._lib.CC_SHA224_Update, self._lib.CC_SHA224_Final
+            ),
+            b"sha256": self.hashtuple(
+                "CC_SHA256_CTX *", self._lib.CC_SHA256_Init,
+                self._lib.CC_SHA256_Update, self._lib.CC_SHA256_Final
+            ),
+            b"sha384": self.hashtuple(
+                "CC_SHA512_CTX *", self._lib.CC_SHA384_Init,
+                self._lib.CC_SHA384_Update, self._lib.CC_SHA384_Final
+            ),
+            b"sha512": self.hashtuple(
+                "CC_SHA512_CTX *", self._lib.CC_SHA512_Init,
+                self._lib.CC_SHA512_Update, self._lib.CC_SHA512_Final
+            ),
+        }
+
+    def hash_supported(self, algorithm):
+        try:
+            self.hash_methods[algorithm.name.encode("ascii")]
+            return True
+        except KeyError:
+            return False
+
+    def create_hash_ctx(self, algorithm):
+        return _HashContext(self, algorithm)
+
+
+@utils.register_interface(interfaces.HashContext)
+class _HashContext(object):
+    def __init__(self, backend, algorithm, ctx=None):
+        self.algorithm = algorithm
+        self._backend = backend
+
+        if ctx is None:
+            try:
+                methods = self._backend.hash_methods[
+                    self.algorithm.name.encode("ascii")
+                ]
+            except KeyError:
+                raise UnsupportedAlgorithm(
+                    "{0} is not a supported hash on this backend".format(
+                        algorithm.name)
+                )
+            ctx = self._backend._ffi.new(methods.struct)
+            res = methods.init(ctx)
+            assert res == 1
+
+        self._ctx = ctx
+
+    def copy(self):
+        methods = self._backend.hash_methods[
+            self.algorithm.name.encode("ascii")
+        ]
+        new_ctx = self._backend._ffi.new(methods.struct)
+        # CommonCrypto has no APIs for copying hashes, so we have to copy the
+        # underlying struct.
+        new_ctx[0] = self._ctx[0]
+
+        return _HashContext(self._backend, self.algorithm, ctx=new_ctx)
+
+    def update(self, data):
+        methods = self._backend.hash_methods[
+            self.algorithm.name.encode("ascii")
+        ]
+        res = methods.update(self._ctx, data, len(data))
+        assert res == 1
+
+    def finalize(self):
+        methods = self._backend.hash_methods[
+            self.algorithm.name.encode("ascii")
+        ]
+        buf = self._backend._ffi.new("unsigned char[]",
+                                     self.algorithm.digest_size)
+        res = methods.final(buf, self._ctx)
+        assert res == 1
+        return self._backend._ffi.buffer(buf)[:]
+
+
+backend = Backend()
diff --git a/docs/hazmat/backends/common-crypto.rst b/docs/hazmat/backends/common-crypto.rst
new file mode 100644
index 0000000..edd45b6
--- /dev/null
+++ b/docs/hazmat/backends/common-crypto.rst
@@ -0,0 +1,28 @@
+.. hazmat::
+
+CommonCrypto Backend
+====================
+
+These are `CFFI`_ bindings to the `CommonCrypto`_ C library provided by Apple
+on OS X and iOS.
+
+.. currentmodule:: cryptography.hazmat.backends.commoncrypto.backend
+
+.. data:: cryptography.hazmat.backends.commoncrypto.backend
+
+    This is the exposed API for the CommonCrypto bindings. It has two public
+    attributes:
+
+    .. attribute:: ffi
+
+        This is a :class:`cffi.FFI` instance. It can be used to allocate and
+        otherwise manipulate CommonCrypto structures.
+
+    .. attribute:: lib
+
+        This is a ``cffi`` library. It can be used to call CommonCrypto
+        functions, and access constants.
+
+
+.. _`CFFI`: https://cffi.readthedocs.org/
+.. _`CommonCrypto`: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/Common%20Crypto.3cc.html
diff --git a/docs/hazmat/backends/index.rst b/docs/hazmat/backends/index.rst
index 0695128..22354f6 100644
--- a/docs/hazmat/backends/index.rst
+++ b/docs/hazmat/backends/index.rst
@@ -31,4 +31,5 @@
     :maxdepth: 1
 
     openssl
+    common-crypto
     interfaces
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 97356c2..b17bcde 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -26,3 +26,4 @@
 Docstrings
 Fernet
 Schneier
+iOS