add AES CTR support to OpenSSL 0.9.8
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 8853646..d7110f8 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -132,6 +132,14 @@
         return _HashContext(self, algorithm)
 
     def cipher_supported(self, cipher, mode):
+        if self._cipher_supported(cipher, mode):
+            return True
+        elif isinstance(mode, CTR) and isinstance(cipher, AES):
+            return True
+        else:
+            return False
+
+    def _cipher_supported(self, cipher, mode):
         try:
             adapter = self._cipher_registry[type(cipher), type(mode)]
         except KeyError:
@@ -198,10 +206,18 @@
         )
 
     def create_symmetric_encryption_ctx(self, cipher, mode):
-        return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT)
+        if (isinstance(mode, CTR) and isinstance(cipher, AES)
+                and not self._cipher_supported(cipher, mode)):
+            return _AESCTRCipherContext(self, cipher, mode)
+        else:
+            return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT)
 
     def create_symmetric_decryption_ctx(self, cipher, mode):
-        return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)
+        if (isinstance(mode, CTR) and isinstance(cipher, AES)
+                and not self._cipher_supported(cipher, mode)):
+            return _AESCTRCipherContext(self, cipher, mode)
+        else:
+            return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)
 
     def pbkdf2_hmac_supported(self, algorithm):
         if self._lib.Cryptography_HAS_PBKDF2_HMAC:
@@ -834,6 +850,37 @@
         return self._tag
 
 
+@utils.register_interface(interfaces.CipherContext)
+class _AESCTRCipherContext(object):
+    def __init__(self, backend, cipher, mode):
+        self._backend = backend
+
+        self._key = self._backend._ffi.new("AES_KEY *")
+        assert self._key != self._backend._ffi.NULL
+        res = self._backend._lib.AES_set_encrypt_key(
+            cipher.key, len(cipher.key) * 8, self._key
+        )
+        assert res == 0
+        self._ecount = self._backend._ffi.new("char[]", 16)
+        self._nonce = self._backend._ffi.new("char[]", mode.nonce)
+        self._num = self._backend._ffi.new("unsigned int *", 0)
+
+    def update(self, data):
+        buf = self._backend._ffi.new("unsigned char[]", len(data))
+        self._backend._lib.AES_ctr128_encrypt(
+            data, buf, len(data), self._key, self._nonce,
+            self._ecount, self._num
+        )
+        return self._backend._ffi.buffer(buf)[:]
+
+    def finalize(self):
+        self._key = None
+        self._ecount = None
+        self._nonce = None
+        self._num = None
+        return b""
+
+
 @utils.register_interface(interfaces.HashContext)
 class _HashContext(object):
     def __init__(self, backend, algorithm, ctx=None):
diff --git a/cryptography/hazmat/bindings/openssl/aes.py b/cryptography/hazmat/bindings/openssl/aes.py
index 17c154c..b0e0072 100644
--- a/cryptography/hazmat/bindings/openssl/aes.py
+++ b/cryptography/hazmat/bindings/openssl/aes.py
@@ -29,6 +29,12 @@
 FUNCTIONS = """
 int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *);
 int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *);
+/* The ctr128_encrypt function is only useful in 0.9.8. You should use EVP for
+   this in 1.0.0+. */
+void AES_ctr128_encrypt(const unsigned char *, unsigned char *,
+                        const unsigned long, const AES_KEY *,
+                        unsigned char[], unsigned char[], unsigned int *);
+
 """
 
 MACROS = """