| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  Cipher/AES.py : AES | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							|  |  |  | # The contents of this file are dedicated to the public domain.  To | 
					
						
							|  |  |  | # the extent that dedication to the public domain is not available, | 
					
						
							|  |  |  | # everyone is granted a worldwide, perpetual, royalty-free, | 
					
						
							|  |  |  | # non-exclusive license to exercise all rights associated with the | 
					
						
							|  |  |  | # contents of this file for any purpose whatsoever. | 
					
						
							|  |  |  | # No rights are reserved. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
					
						
							|  |  |  | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
					
						
							|  |  |  | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
					
						
							|  |  |  | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
					
						
							|  |  |  | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
					
						
							|  |  |  | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
					
						
							|  |  |  | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
					
						
							|  |  |  | # SOFTWARE. | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							|  |  |  | """AES symmetric cipher
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AES `(Advanced Encryption Standard)`__ is a symmetric block cipher standardized | 
					
						
							|  |  |  | by NIST_ . It has a fixed data block size of 16 bytes. | 
					
						
							| 
									
										
										
										
											2012-05-14 23:50:40 +02:00
										 |  |  | Its keys can be 128, 192, or 256 bits long. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | AES is very fast and secure, and it is the de facto standard for symmetric | 
					
						
							|  |  |  | encryption. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-14 23:50:40 +02:00
										 |  |  | As an example, encryption can be done as follows: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> from Crypto.Cipher import AES | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  |     >>> from Crypto.Random import get_random_bytes | 
					
						
							| 
									
										
										
										
											2012-05-14 23:50:40 +02:00
										 |  |  |     >>> | 
					
						
							|  |  |  |     >>> key = b'Sixteen byte key' | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  |     >>> iv = get_random_bytes(16) | 
					
						
							| 
									
										
										
										
											2012-05-14 23:50:40 +02:00
										 |  |  |     >>> cipher = AES.new(key, AES.MODE_CFB, iv) | 
					
						
							|  |  |  |     >>> msg = iv + cipher.encrypt(b'Attack at dawn') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  | A more complicated example is based on CCM, (see `MODE_CCM`) an `AEAD`_ mode | 
					
						
							|  |  |  | that provides both confidentiality and authentication for a message. | 
					
						
							| 
									
										
										
										
											2013-12-17 22:09:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  | It optionally allows the header of the message to remain in the clear, | 
					
						
							|  |  |  | whilst still being authenticated. The encryption is done as follows: | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     >>> from Crypto.Cipher import AES | 
					
						
							|  |  |  |     >>> from Crypto.Random import get_random_bytes | 
					
						
							|  |  |  |     >>> | 
					
						
							|  |  |  |     >>> | 
					
						
							|  |  |  |     >>> hdr = b'To your eyes only' | 
					
						
							|  |  |  |     >>> plaintext = b'Attack at dawn' | 
					
						
							|  |  |  |     >>> key = b'Sixteen byte key' | 
					
						
							|  |  |  |     >>> nonce = get_random_bytes(11) | 
					
						
							|  |  |  |     >>> cipher = AES.new(key, AES.MODE_CCM, nonce) | 
					
						
							|  |  |  |     >>> cipher.update(hdr) | 
					
						
							|  |  |  |     >>> msg = nonce, hdr, cipher.encrypt(plaintext), cipher.digest() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | We assume that the tuple ``msg`` is transmitted to the receiver: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> nonce, hdr, ciphertext, mac = msg | 
					
						
							|  |  |  |     >>> key = b'Sixteen byte key' | 
					
						
							|  |  |  |     >>> cipher = AES.new(key, AES.MODE_CCM, nonce) | 
					
						
							|  |  |  |     >>> cipher.update(hdr) | 
					
						
							|  |  |  |     >>> plaintext = cipher.decrypt(ciphertext) | 
					
						
							|  |  |  |     >>> try: | 
					
						
							|  |  |  |     >>>     cipher.verify(mac) | 
					
						
							|  |  |  |     >>>     print "The message is authentic: hdr=%s, pt=%s" % (hdr, plaintext) | 
					
						
							|  |  |  |     >>> except ValueError: | 
					
						
							|  |  |  |     >>>     print "Key incorrect or message corrupted" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | .. __: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard | 
					
						
							|  |  |  | .. _NIST: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  | .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from Crypto.Cipher import _create_cipher | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  | from Crypto.Util._raw_api import (load_pycryptodome_raw_lib, | 
					
						
							| 
									
										
										
										
											2015-02-10 22:29:40 +01:00
										 |  |  |                                   VoidPointer, SmartPointer, | 
					
						
							|  |  |  |                                   c_size_t, expect_byte_string) | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 15:24:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-02 21:40:34 +01:00
										 |  |  | _raw_cpuid_lib = load_pycryptodome_raw_lib("Crypto.Util._cpuid", | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |                                            "int have_aes_ni(void);") | 
					
						
							| 
									
										
										
										
											2015-01-23 15:24:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  | cproto = """
 | 
					
						
							|  |  |  |         int AES_start_operation(const uint8_t key[], | 
					
						
							|  |  |  |                                 size_t key_len, | 
					
						
							|  |  |  |                                 void **pResult); | 
					
						
							|  |  |  |         int AES_encrypt(const void *state, | 
					
						
							|  |  |  |                         const uint8_t *in, | 
					
						
							|  |  |  |                         uint8_t *out, | 
					
						
							|  |  |  |                         size_t data_len); | 
					
						
							|  |  |  |         int AES_decrypt(const void *state, | 
					
						
							|  |  |  |                         const uint8_t *in, | 
					
						
							|  |  |  |                         uint8_t *out, | 
					
						
							|  |  |  |                         size_t data_len); | 
					
						
							|  |  |  |         int AES_stop_operation(void *state); | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _raw_aes_lib = load_pycryptodome_raw_lib("Crypto.Cipher._raw_aes", | 
					
						
							|  |  |  |                                          cproto) | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | _raw_aesni_lib = None | 
					
						
							| 
									
										
										
										
											2013-02-04 14:44:29 +01:00
										 |  |  | try: | 
					
						
							| 
									
										
										
										
											2015-01-23 15:24:21 +00:00
										 |  |  |     if _raw_cpuid_lib.have_aes_ni() == 1: | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  |         _raw_aesni_lib = load_pycryptodome_raw_lib("Crypto.Cipher._raw_aesni", | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |                                                    cproto.replace("AES", | 
					
						
							|  |  |  |                                                                   "AESNI")) | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  | except OSError: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _create_base_cipher(dict_parameters): | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |     """This method instantiates and returns a handle to a low-level
 | 
					
						
							|  |  |  |     base cipher. It will absorb named parameters in the process."""
 | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     use_aesni = dict_parameters.pop("use_aesni", True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         key = dict_parameters.pop("key") | 
					
						
							|  |  |  |     except KeyError: | 
					
						
							|  |  |  |         raise TypeError("Missing 'key' parameter") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-10 22:29:40 +01:00
										 |  |  |     expect_byte_string(key) | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if len(key) not in key_size: | 
					
						
							|  |  |  |         raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if use_aesni and _raw_aesni_lib: | 
					
						
							|  |  |  |         start_operation = _raw_aesni_lib.AESNI_start_operation | 
					
						
							|  |  |  |         stop_operation = _raw_aesni_lib.AESNI_stop_operation | 
					
						
							| 
									
										
										
										
											2013-02-04 14:44:29 +01:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  |         start_operation = _raw_aes_lib.AES_start_operation | 
					
						
							|  |  |  |         stop_operation = _raw_aes_lib.AES_stop_operation | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  |     cipher = VoidPointer() | 
					
						
							|  |  |  |     result = start_operation(key, | 
					
						
							| 
									
										
										
										
											2015-02-10 16:45:25 +01:00
										 |  |  |                              c_size_t(len(key)), | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  |                              cipher.address_of()) | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  |     if result: | 
					
						
							|  |  |  |         raise ValueError("Error %X while instantiating the AES cipher" | 
					
						
							|  |  |  |                          % result) | 
					
						
							| 
									
										
										
										
											2015-01-19 14:00:35 +01:00
										 |  |  |     return SmartPointer(cipher.get(), stop_operation) | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-07 18:42:52 +02:00
										 |  |  | def new(key, mode, *args, **kwargs): | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  |     """Create a new AES cipher
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     :Parameters: | 
					
						
							|  |  |  |       key : byte string | 
					
						
							|  |  |  |         The secret key to use in the symmetric cipher. | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |         It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) | 
					
						
							|  |  |  |         bytes long. | 
					
						
							| 
									
										
										
										
											2013-05-22 22:18:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Only in `MODE_SIV`, it needs to be 32, 48, or 64 bytes long. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  |       mode : a *MODE_** constant | 
					
						
							|  |  |  |         The chaining mode to use for encryption or decryption. | 
					
						
							| 
									
										
										
										
											2014-06-07 18:42:52 +02:00
										 |  |  |     :Keywords: | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  |       IV : byte string | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  |         (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  |         The initialization vector to use for encryption or decryption. | 
					
						
							| 
									
										
										
										
											2013-12-17 22:09:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-17 13:28:24 +02:00
										 |  |  |         It is ignored for `MODE_ECB` and `MODE_CTR`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption | 
					
						
							|  |  |  |         and `block_size` +2 bytes for decryption (in the latter case, it is | 
					
						
							|  |  |  |         actually the *encrypted* IV which was prefixed to the ciphertext). | 
					
						
							|  |  |  |         It is mandatory. | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         For all other modes, it must be 16 bytes long. | 
					
						
							|  |  |  |       nonce : byte string | 
					
						
							| 
									
										
										
										
											2013-05-28 23:57:56 +02:00
										 |  |  |         (*Only* `MODE_CCM`, `MODE_EAX`, `MODE_GCM`, `MODE_SIV`). | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         A mandatory value that must never be reused for any other encryption. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         For `MODE_CCM`, its length must be in the range ``[7..13]``. | 
					
						
							|  |  |  |         11 or 12 bytes are reasonable values in general. Bear in | 
					
						
							|  |  |  |         mind that with CCM there is a trade-off between nonce length and | 
					
						
							|  |  |  |         maximum message size. | 
					
						
							| 
									
										
										
										
											2013-05-20 12:43:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         For the other modes, there are no restrictions on its length, | 
					
						
							|  |  |  |         but it is recommended to use at least 16 bytes. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  |       counter : callable | 
					
						
							|  |  |  |         (*Only* `MODE_CTR`). A stateful function that returns the next | 
					
						
							|  |  |  |         *counter block*, which is a byte string of `block_size` bytes. | 
					
						
							|  |  |  |         For better performance, use `Crypto.Util.Counter`. | 
					
						
							|  |  |  |       segment_size : integer | 
					
						
							|  |  |  |         (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext | 
					
						
							|  |  |  |         are segmented in. | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |         It must be a multiple of 8. If 0 or not specified, | 
					
						
							|  |  |  |         it will be assumed to be 8. | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  |       mac_len : integer | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |         (*Only* `MODE_CCM`). Length of the MAC, in bytes. It must be even | 
					
						
							|  |  |  |         and in the range ``[4..16]``. The default is 16. | 
					
						
							| 
									
										
										
										
											2013-05-20 12:43:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |         (*Only* `MODE_EAX` and `MODE_GCM`). Length of the MAC, in bytes. | 
					
						
							|  |  |  |         It must be no larger than 16 bytes (which is the default). | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  |       msg_len : integer | 
					
						
							|  |  |  |         (*Only* `MODE_CCM`). Length of the message to (de)cipher. | 
					
						
							|  |  |  |         If not specified, ``encrypt`` or ``decrypt`` may only be called once. | 
					
						
							|  |  |  |       assoc_len : integer | 
					
						
							|  |  |  |         (*Only* `MODE_CCM`). Length of the associated data. | 
					
						
							|  |  |  |         If not specified, all data is internally buffered. | 
					
						
							| 
									
										
										
										
											2013-02-04 14:44:29 +01:00
										 |  |  |       use_aesni : boolean | 
					
						
							|  |  |  |         Use AES-NI if available. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  |     :Return: an AES object, of the applicable mode. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2014-12-07 19:55:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 21:40:49 +01:00
										 |  |  |     kwargs["add_aes_modes"] = True | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  |     return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Electronic Code Book (ECB). See `Crypto.Cipher._mode_ecb.EcbMode`. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | MODE_ECB = 1 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Cipher-Block Chaining (CBC). See `Crypto.Cipher._mode_cbc.CbcMode`. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | MODE_CBC = 2 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Cipher FeedBack (CFB). See `Crypto.Cipher._mode_cfb.CfbMode`. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | MODE_CFB = 3 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Output FeedBack (OFB). See `Crypto.Cipher._mode_ofb.OfbMode`. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | MODE_OFB = 5 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: CounTer Mode (CTR). See `Crypto.Cipher._mode_ctr.CtrMode`. | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | MODE_CTR = 6 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: OpenPGP Mode. See `Crypto.Cipher._mode_openpgp.OpenPgpMode`. | 
					
						
							| 
									
										
										
										
											2012-05-17 13:28:24 +02:00
										 |  |  | MODE_OPENPGP = 7 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Counter with CBC-MAC (CCM) Mode. See `Crypto.Cipher._mode_ccm.CcmMode`. | 
					
						
							| 
									
										
										
										
											2013-01-23 22:37:53 +01:00
										 |  |  | MODE_CCM = 8 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: EAX Mode. See `Crypto.Cipher._mode_eax.EaxMode`. | 
					
						
							| 
									
										
										
										
											2013-05-20 12:43:44 +02:00
										 |  |  | MODE_EAX = 9 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Syntethic Initialization Vector (SIV). See `Crypto.Cipher._mode_siv.SivMode`. | 
					
						
							| 
									
										
										
										
											2013-05-22 22:18:35 +02:00
										 |  |  | MODE_SIV = 10 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | #: Galois Counter Mode (GCM). See `Crypto.Cipher._mode_gcm.GcmMode`. | 
					
						
							| 
									
										
										
										
											2013-05-28 23:57:56 +02:00
										 |  |  | MODE_GCM = 11 | 
					
						
							| 
									
										
										
										
											2015-03-09 21:43:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-09 20:55:07 +02:00
										 |  |  | #: Size of a data block (in bytes) | 
					
						
							|  |  |  | block_size = 16 | 
					
						
							|  |  |  | #: Size of a key (in bytes) | 
					
						
							| 
									
										
										
										
											2014-12-16 07:50:48 +01:00
										 |  |  | key_size = (16, 24, 32) |