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:
