Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign up| PEP: 272 | |
| Title: API for Block Encryption Algorithms v1.0 | |
| Version: $Revision$ | |
| Last-Modified: $Date$ | |
| Author: A.M. Kuchling <amk@amk.ca> | |
| Status: Final | |
| Type: Informational | |
| Content-Type: text/x-rst | |
| Created: 18-Sep-2001 | |
| Post-History: 17-Apr-2002, 29-May-2002 | |
| Abstract | |
| ======== | |
| This document specifies a standard API for secret-key block | |
| encryption algorithms such as DES or Rijndael, making it easier to | |
| switch between different algorithms and implementations. | |
| Introduction | |
| ============ | |
| Encryption algorithms transform their input data (called | |
| plaintext) in some way that is dependent on a variable key, | |
| producing ciphertext. The transformation can easily be reversed | |
| if and only if one knows the key. The key is a sequence of bits | |
| chosen from some very large space of possible keys. There are two | |
| classes of encryption algorithms: block ciphers and stream ciphers. | |
| Block ciphers encrypt multibyte inputs of a fixed size (frequently | |
| 8 or 16 bytes long), and can be operated in various feedback | |
| modes. The feedback modes supported in this specification are: | |
| ====== ======== ===================== | |
| Number Constant Description | |
| ====== ======== ===================== | |
| 1 MODE_ECB Electronic Code Book | |
| 2 MODE_CBC Cipher Block Chaining | |
| 3 MODE_CFB Cipher Feedback | |
| 5 MODE_OFB Output Feedback | |
| 6 MODE_CTR Counter | |
| ====== ======== ===================== | |
| These modes are to be implemented as described in NIST publication | |
| SP 800-38A [1]_. Descriptions of the first three feedback modes can | |
| also be found in Bruce Schneier's book *Applied Cryptography* [2]_. | |
| (The numeric value 4 is reserved for MODE_PGP, a variant of CFB | |
| described in RFC 2440: "OpenPGP Message Format" [3]_. This mode | |
| isn't considered important enough to make it worth requiring it | |
| for all block encryption ciphers, though supporting it is a nice | |
| extra feature.) | |
| In a strict formal sense, stream ciphers encrypt data bit-by-bit; | |
| practically, stream ciphers work on a character-by-character | |
| basis. This PEP only aims at specifying an interface for block | |
| ciphers, though stream ciphers can support the interface described | |
| here by fixing 'block_size' to 1. Feedback modes also don't make | |
| sense for stream ciphers, so the only reasonable feedback mode | |
| would be ECB mode. | |
| Specification | |
| ============= | |
| Encryption modules can add additional functions, methods, and | |
| attributes beyond those described in this PEP, but all of the | |
| features described in this PEP must be present for a module to | |
| claim compliance with it. | |
| Secret-key encryption modules should define one function:: | |
| new(key, mode, [IV], **kwargs) | |
| Returns a ciphering object, using the secret key contained in the | |
| string 'key', and using the feedback mode 'mode', which must be | |
| one of the constants from the table above. | |
| If 'mode' is MODE_CBC or MODE_CFB, 'IV' must be provided and must | |
| be a string of the same length as the block size. Not providing a | |
| value of 'IV' will result in a ``ValueError`` exception being raised. | |
| Depending on the algorithm, a module may support additional | |
| keyword arguments to this function. Some keyword arguments are | |
| specified by this PEP, and modules are free to add additional | |
| keyword arguments. If a value isn't provided for a given keyword, | |
| a secure default value should be used. For example, if an | |
| algorithm has a selectable number of rounds between 1 and 16, and | |
| 1-round encryption is insecure and 8-round encryption is believed | |
| secure, the default value for 'rounds' should be 8 or more. | |
| (Module implementors can choose a very slow but secure value, too, | |
| such as 16 in this example. This decision is left up to the | |
| implementor.) | |
| The following table lists keyword arguments defined by this PEP: | |
| ============ ============================================ | |
| Keyword Meaning | |
| ============ ============================================ | |
| counter Callable object that returns counter blocks | |
| (see below; CTR mode only) | |
| rounds Number of rounds of encryption to use | |
| segment_size Size of data and ciphertext segments, | |
| measured in bits (see below; CFB mode only) | |
| ============ ============================================ | |
| The Counter feedback mode requires a sequence of input blocks, | |
| called counters, that are used to produce the output. When 'mode' | |
| is MODE_CTR, the 'counter' keyword argument must be provided, and | |
| its value must be a callable object, such as a function or method. | |
| Successive calls to this callable object must return a sequence of | |
| strings that are of the length 'block_size' and that never | |
| repeats. (Appendix B of the NIST publication gives a way to | |
| generate such a sequence, but that's beyond the scope of this | |
| PEP.) | |
| The CFB mode operates on segments of the plaintext and ciphertext | |
| that are 'segment_size' bits long. Therefore, when using this | |
| mode, the input and output strings must be a multiple of | |
| 'segment_size' bits in length. 'segment_size' must be an integer | |
| between 1 and block_size\*8, inclusive. (The factor of 8 comes | |
| from 'block_size' being measured in bytes and not in bits). The | |
| default value for this parameter should be block_size\*8. | |
| Implementors are allowed to constrain 'segment_size' to be a | |
| multiple of 8 for simplicity, but they're encouraged to support | |
| arbitrary values for generality. | |
| Secret-key encryption modules should define two variables: | |
| - block_size | |
| An integer value; the size of the blocks encrypted by this | |
| module, measured in bytes. For all feedback modes, the length | |
| of strings passed to the encrypt() and decrypt() must be a | |
| multiple of the block size. | |
| - key_size | |
| An integer value; the size of the keys required by this | |
| module, measured in bytes. If key_size is None, then the | |
| algorithm accepts variable-length keys. This may mean the | |
| module accepts keys of any random length, or that there are a | |
| few different possible lengths, e.g. 16, 24, or 32 bytes. You | |
| cannot pass a key of length 0 (that is, the null string '') as | |
| a variable-length key. | |
| Cipher objects should have two attributes: | |
| - block_size | |
| An integer value equal to the size of the blocks encrypted by | |
| this object. For algorithms with a variable block size, this | |
| value is equal to the block size selected for this object. | |
| - IV | |
| Contains the initial value which will be used to start a | |
| cipher feedback mode; it will always be a string exactly one | |
| block in length. After encrypting or decrypting a string, | |
| this value is updated to reflect the modified feedback text. | |
| It is read-only, and cannot be assigned a new value. | |
| Cipher objects require the following methods: | |
| - decrypt(string) | |
| Decrypts 'string', using the key-dependent data in the object | |
| and with the appropriate feedback mode. The string's length | |
| must be an exact multiple of the algorithm's block size or, in | |
| CFB mode, of the segment size. Returns a string containing | |
| the plaintext. | |
| - encrypt(string) | |
| Encrypts a non-empty string, using the key-dependent data in | |
| the object, and with the appropriate feedback mode. The | |
| string's length must be an exact multiple of the algorithm's | |
| block size or, in CFB mode, of the segment size. Returns a | |
| string containing the ciphertext. | |
| Here's an example, using a module named 'DES':: | |
| >>> import DES | |
| >>> obj = DES.new('abcdefgh', DES.MODE_ECB) | |
| >>> plaintext = "Guido van Rossum is a space alien." | |
| >>> len(plaintext) | |
| 34 | |
| >>> obj.encrypt(plaintext) | |
| Traceback (innermost last): | |
| File "<stdin>", line 1, in ? | |
| ValueError: Strings for DES must be a multiple of 8 in length | |
| >>> ciphertext = obj.encrypt(plain+'XXXXXX') # Add padding | |
| >>> ciphertext | |
| '\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006' | |
| >>> obj.decrypt(ciphertext) | |
| 'Guido van Rossum is a space alien.XXXXXX' | |
| References | |
| ========== | |
| .. [1] NIST publication SP 800-38A, "Recommendation for Block Cipher | |
| Modes of Operation" (http://csrc.nist.gov/encryption/modes/) | |
| .. [2] Applied Cryptography | |
| .. [3] RFC2440: "OpenPGP Message Format" (http://rfc2440.x42.com, | |
| http://www.faqs.org/rfcs/rfc2440.html) | |
| Changes | |
| ======= | |
| 2002-04: Removed references to stream ciphers; retitled PEP; | |
| prefixed feedback mode constants with ``MODE_``; removed PGP feedback | |
| mode; added CTR and OFB feedback modes; clarified where numbers | |
| are measured in bytes and where in bits. | |
| 2002-09: Clarified the discussion of key length by using | |
| "variable-length keys" instead of "arbitrary-length". | |
| Acknowledgements | |
| ================ | |
| Thanks to the readers of the python-crypto list for their comments on | |
| this PEP. | |
| Copyright | |
| ========= | |
| This document has been placed in the public domain. | |
| .. | |
| Local Variables: | |
| mode: indented-text | |
| indent-tabs-mode: nil | |
| End: | |