225 lines
8.6 KiB
Plaintext
225 lines
8.6 KiB
Plaintext
PEP: 272
|
||
Title: API for Block Encryption Algorithms
|
||
Version: $Revision$
|
||
Author: A.M. Kuchling <akuchlin@mems-exchange.org>
|
||
Status: Draft
|
||
Type: Informational
|
||
Created: 18-Sep-2001
|
||
Post-History: 17-Apr-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 arbitrary-length keys. You cannot pass a
|
||
key of length 0 (that is, the null string '') as such 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.
|
||
|
||
|
||
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:
|
||
|