We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Raise clearer error message when passing a unicode value as a symmetric key
Python: 2.7.3
cryptography==2.1.4
cffi==1.11.5
pip 9.0.1

```
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os

iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CFB8(iv),
                            backend=default_backend())
decryptor = cipher.decryptor()
raw_text = decryptor.update(encoded_text) + decryptor.finalize()
```

If `key` is unicode it will raise error.
```

/env/local/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.pyc in decryptor(self)
    125     def decryptor(self):
    126         ctx = self._backend.create_symmetric_decryption_ctx(
--> 127             self.algorithm, self.mode
    128         )
    129         return self._wrap_ctx(ctx, encrypt=False)

/env/local/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.pyc in create_symmetric_decryption_ctx(self, cipher, mode)
    270 
    271     def create_symmetric_decryption_ctx(self, cipher, mode):
--> 272         return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)
    273 
    274     def pbkdf2_hmac_supported(self, algorithm):

/env/local/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.pyc in __init__(self, backend, cipher, mode, operation)
    108             cipher.key,
    109             iv_nonce,
--> 110             operation
    111         )
    112         self._backend.openssl_assert(res != 0)
``` 

I have this fix temporary
```key = key.encode('utf-8') if isinstance(key, unicode) else key```
But should we do thi in `backends/openssl/ciphers.py` ?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cryptography/hazmat/primitives/ciphers/algorithms.py`
Content:
```
1 # This file is dual licensed under the terms of the Apache License, Version
2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 # for complete details.
4 
5 from __future__ import absolute_import, division, print_function
6 
7 from cryptography import utils
8 from cryptography.hazmat.primitives.ciphers import (
9     BlockCipherAlgorithm, CipherAlgorithm
10 )
11 from cryptography.hazmat.primitives.ciphers.modes import ModeWithNonce
12 
13 
14 def _verify_key_size(algorithm, key):
15     # Verify that the key size matches the expected key size
16     if len(key) * 8 not in algorithm.key_sizes:
17         raise ValueError("Invalid key size ({0}) for {1}.".format(
18             len(key) * 8, algorithm.name
19         ))
20     return key
21 
22 
23 @utils.register_interface(BlockCipherAlgorithm)
24 @utils.register_interface(CipherAlgorithm)
25 class AES(object):
26     name = "AES"
27     block_size = 128
28     # 512 added to support AES-256-XTS, which uses 512-bit keys
29     key_sizes = frozenset([128, 192, 256, 512])
30 
31     def __init__(self, key):
32         self.key = _verify_key_size(self, key)
33 
34     @property
35     def key_size(self):
36         return len(self.key) * 8
37 
38 
39 @utils.register_interface(BlockCipherAlgorithm)
40 @utils.register_interface(CipherAlgorithm)
41 class Camellia(object):
42     name = "camellia"
43     block_size = 128
44     key_sizes = frozenset([128, 192, 256])
45 
46     def __init__(self, key):
47         self.key = _verify_key_size(self, key)
48 
49     @property
50     def key_size(self):
51         return len(self.key) * 8
52 
53 
54 @utils.register_interface(BlockCipherAlgorithm)
55 @utils.register_interface(CipherAlgorithm)
56 class TripleDES(object):
57     name = "3DES"
58     block_size = 64
59     key_sizes = frozenset([64, 128, 192])
60 
61     def __init__(self, key):
62         if len(key) == 8:
63             key += key + key
64         elif len(key) == 16:
65             key += key[:8]
66         self.key = _verify_key_size(self, key)
67 
68     @property
69     def key_size(self):
70         return len(self.key) * 8
71 
72 
73 @utils.register_interface(BlockCipherAlgorithm)
74 @utils.register_interface(CipherAlgorithm)
75 class Blowfish(object):
76     name = "Blowfish"
77     block_size = 64
78     key_sizes = frozenset(range(32, 449, 8))
79 
80     def __init__(self, key):
81         self.key = _verify_key_size(self, key)
82 
83     @property
84     def key_size(self):
85         return len(self.key) * 8
86 
87 
88 @utils.register_interface(BlockCipherAlgorithm)
89 @utils.register_interface(CipherAlgorithm)
90 class CAST5(object):
91     name = "CAST5"
92     block_size = 64
93     key_sizes = frozenset(range(40, 129, 8))
94 
95     def __init__(self, key):
96         self.key = _verify_key_size(self, key)
97 
98     @property
99     def key_size(self):
100         return len(self.key) * 8
101 
102 
103 @utils.register_interface(CipherAlgorithm)
104 class ARC4(object):
105     name = "RC4"
106     key_sizes = frozenset([40, 56, 64, 80, 128, 160, 192, 256])
107 
108     def __init__(self, key):
109         self.key = _verify_key_size(self, key)
110 
111     @property
112     def key_size(self):
113         return len(self.key) * 8
114 
115 
116 @utils.register_interface(CipherAlgorithm)
117 class IDEA(object):
118     name = "IDEA"
119     block_size = 64
120     key_sizes = frozenset([128])
121 
122     def __init__(self, key):
123         self.key = _verify_key_size(self, key)
124 
125     @property
126     def key_size(self):
127         return len(self.key) * 8
128 
129 
130 @utils.register_interface(BlockCipherAlgorithm)
131 @utils.register_interface(CipherAlgorithm)
132 class SEED(object):
133     name = "SEED"
134     block_size = 128
135     key_sizes = frozenset([128])
136 
137     def __init__(self, key):
138         self.key = _verify_key_size(self, key)
139 
140     @property
141     def key_size(self):
142         return len(self.key) * 8
143 
144 
145 @utils.register_interface(CipherAlgorithm)
146 @utils.register_interface(ModeWithNonce)
147 class ChaCha20(object):
148     name = "ChaCha20"
149     key_sizes = frozenset([256])
150 
151     def __init__(self, key, nonce):
152         self.key = _verify_key_size(self, key)
153         if not isinstance(nonce, bytes):
154             raise TypeError("nonce must be bytes")
155 
156         if len(nonce) != 16:
157             raise ValueError("nonce must be 128-bits (16 bytes)")
158 
159         self._nonce = nonce
160 
161     nonce = utils.read_only_property("_nonce")
162 
163     @property
164     def key_size(self):
165         return len(self.key) * 8
166
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cryptography/hazmat/primitives/ciphers/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py
--- a/src/cryptography/hazmat/primitives/ciphers/algorithms.py
+++ b/src/cryptography/hazmat/primitives/ciphers/algorithms.py
@@ -12,6 +12,9 @@
 
 
 def _verify_key_size(algorithm, key):
+    # Verify that the key is instance of bytes
+    utils._check_bytes("key", key)
+
     # Verify that the key size matches the expected key size
     if len(key) * 8 not in algorithm.key_sizes:
         raise ValueError("Invalid key size ({0}) for {1}.".format(

{"golden_diff": "diff --git a/src/cryptography/hazmat/primitives/ciphers/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py\n--- a/src/cryptography/hazmat/primitives/ciphers/algorithms.py\n+++ b/src/cryptography/hazmat/primitives/ciphers/algorithms.py\n@@ -12,6 +12,9 @@\n \n \n def _verify_key_size(algorithm, key):\n+    # Verify that the key is instance of bytes\n+    utils._check_bytes(\"key\", key)\n+\n     # Verify that the key size matches the expected key size\n     if len(key) * 8 not in algorithm.key_sizes:\n         raise ValueError(\"Invalid key size ({0}) for {1}.\".format(\n", "issue": "Raise clearer error message when passing a unicode value as a symmetric key\nPython: 2.7.3\r\ncryptography==2.1.4\r\ncffi==1.11.5\r\npip 9.0.1\r\n\r\n```\r\nfrom cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\r\nfrom cryptography.hazmat.backends import default_backend\r\nimport os\r\n\r\niv = os.urandom(16)\r\ncipher = Cipher(algorithms.AES(key), modes.CFB8(iv),\r\n                            backend=default_backend())\r\ndecryptor = cipher.decryptor()\r\nraw_text = decryptor.update(encoded_text) + decryptor.finalize()\r\n```\r\n\r\nIf `key` is unicode it will raise error.\r\n```\r\n\r\n/env/local/lib/python2.7/site-packages/cryptography/hazmat/primitives/ciphers/base.pyc in decryptor(self)\r\n    125     def decryptor(self):\r\n    126         ctx = self._backend.create_symmetric_decryption_ctx(\r\n--> 127             self.algorithm, self.mode\r\n    128         )\r\n    129         return self._wrap_ctx(ctx, encrypt=False)\r\n\r\n/env/local/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.pyc in create_symmetric_decryption_ctx(self, cipher, mode)\r\n    270 \r\n    271     def create_symmetric_decryption_ctx(self, cipher, mode):\r\n--> 272         return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)\r\n    273 \r\n    274     def pbkdf2_hmac_supported(self, algorithm):\r\n\r\n/env/local/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/ciphers.pyc in __init__(self, backend, cipher, mode, operation)\r\n    108             cipher.key,\r\n    109             iv_nonce,\r\n--> 110             operation\r\n    111         )\r\n    112         self._backend.openssl_assert(res != 0)\r\n``` \r\n\r\nI have this fix temporary\r\n```key = key.encode('utf-8') if isinstance(key, unicode) else key```\r\nBut should we do thi in `backends/openssl/ciphers.py` ?\r\n\n", "before_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nfrom cryptography import utils\nfrom cryptography.hazmat.primitives.ciphers import (\n    BlockCipherAlgorithm, CipherAlgorithm\n)\nfrom cryptography.hazmat.primitives.ciphers.modes import ModeWithNonce\n\n\ndef _verify_key_size(algorithm, key):\n    # Verify that the key size matches the expected key size\n    if len(key) * 8 not in algorithm.key_sizes:\n        raise ValueError(\"Invalid key size ({0}) for {1}.\".format(\n            len(key) * 8, algorithm.name\n        ))\n    return key\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass AES(object):\n    name = \"AES\"\n    block_size = 128\n    # 512 added to support AES-256-XTS, which uses 512-bit keys\n    key_sizes = frozenset([128, 192, 256, 512])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass Camellia(object):\n    name = \"camellia\"\n    block_size = 128\n    key_sizes = frozenset([128, 192, 256])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass TripleDES(object):\n    name = \"3DES\"\n    block_size = 64\n    key_sizes = frozenset([64, 128, 192])\n\n    def __init__(self, key):\n        if len(key) == 8:\n            key += key + key\n        elif len(key) == 16:\n            key += key[:8]\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass Blowfish(object):\n    name = \"Blowfish\"\n    block_size = 64\n    key_sizes = frozenset(range(32, 449, 8))\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass CAST5(object):\n    name = \"CAST5\"\n    block_size = 64\n    key_sizes = frozenset(range(40, 129, 8))\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(CipherAlgorithm)\nclass ARC4(object):\n    name = \"RC4\"\n    key_sizes = frozenset([40, 56, 64, 80, 128, 160, 192, 256])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(CipherAlgorithm)\nclass IDEA(object):\n    name = \"IDEA\"\n    block_size = 64\n    key_sizes = frozenset([128])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass SEED(object):\n    name = \"SEED\"\n    block_size = 128\n    key_sizes = frozenset([128])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(CipherAlgorithm)\n@utils.register_interface(ModeWithNonce)\nclass ChaCha20(object):\n    name = \"ChaCha20\"\n    key_sizes = frozenset([256])\n\n    def __init__(self, key, nonce):\n        self.key = _verify_key_size(self, key)\n        if not isinstance(nonce, bytes):\n            raise TypeError(\"nonce must be bytes\")\n\n        if len(nonce) != 16:\n            raise ValueError(\"nonce must be 128-bits (16 bytes)\")\n\n        self._nonce = nonce\n\n    nonce = utils.read_only_property(\"_nonce\")\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n", "path": "src/cryptography/hazmat/primitives/ciphers/algorithms.py"}], "after_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nfrom cryptography import utils\nfrom cryptography.hazmat.primitives.ciphers import (\n    BlockCipherAlgorithm, CipherAlgorithm\n)\nfrom cryptography.hazmat.primitives.ciphers.modes import ModeWithNonce\n\n\ndef _verify_key_size(algorithm, key):\n    # Verify that the key is instance of bytes\n    utils._check_bytes(\"key\", key)\n\n    # Verify that the key size matches the expected key size\n    if len(key) * 8 not in algorithm.key_sizes:\n        raise ValueError(\"Invalid key size ({0}) for {1}.\".format(\n            len(key) * 8, algorithm.name\n        ))\n    return key\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass AES(object):\n    name = \"AES\"\n    block_size = 128\n    # 512 added to support AES-256-XTS, which uses 512-bit keys\n    key_sizes = frozenset([128, 192, 256, 512])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass Camellia(object):\n    name = \"camellia\"\n    block_size = 128\n    key_sizes = frozenset([128, 192, 256])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass TripleDES(object):\n    name = \"3DES\"\n    block_size = 64\n    key_sizes = frozenset([64, 128, 192])\n\n    def __init__(self, key):\n        if len(key) == 8:\n            key += key + key\n        elif len(key) == 16:\n            key += key[:8]\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass Blowfish(object):\n    name = \"Blowfish\"\n    block_size = 64\n    key_sizes = frozenset(range(32, 449, 8))\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass CAST5(object):\n    name = \"CAST5\"\n    block_size = 64\n    key_sizes = frozenset(range(40, 129, 8))\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(CipherAlgorithm)\nclass ARC4(object):\n    name = \"RC4\"\n    key_sizes = frozenset([40, 56, 64, 80, 128, 160, 192, 256])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(CipherAlgorithm)\nclass IDEA(object):\n    name = \"IDEA\"\n    block_size = 64\n    key_sizes = frozenset([128])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(BlockCipherAlgorithm)\n@utils.register_interface(CipherAlgorithm)\nclass SEED(object):\n    name = \"SEED\"\n    block_size = 128\n    key_sizes = frozenset([128])\n\n    def __init__(self, key):\n        self.key = _verify_key_size(self, key)\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n\n\n@utils.register_interface(CipherAlgorithm)\n@utils.register_interface(ModeWithNonce)\nclass ChaCha20(object):\n    name = \"ChaCha20\"\n    key_sizes = frozenset([256])\n\n    def __init__(self, key, nonce):\n        self.key = _verify_key_size(self, key)\n        if not isinstance(nonce, bytes):\n            raise TypeError(\"nonce must be bytes\")\n\n        if len(nonce) != 16:\n            raise ValueError(\"nonce must be 128-bits (16 bytes)\")\n\n        self._nonce = nonce\n\n    nonce = utils.read_only_property(\"_nonce\")\n\n    @property\n    def key_size(self):\n        return len(self.key) * 8\n", "path": "src/cryptography/hazmat/primitives/ciphers/algorithms.py"}]}