[PYTHON-CRYPTO] things missing from PEP 272

Paul Rubin phr-pycrypt at nightsong.com
Mon Mar 18 07:00:22 CET 2002


    The standard NIST cipher modes are defined in this document

    http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf

    The modes it gives are CBC, ECB, CFB, OFB, and CTR, the last two of which
    are missing from PEP 272. Some further justification for CTR is given
    here -

    http://www.cs.berkeley.edu/~daw/papers/ctr-aes00.ps

    I'd really like CTR to ship with Python because, well, I'm using it, and
    it's the only thing keeping my app from being pure Python :-)

I agree that CTR mode should be included.  I think OFB and CFB modes
can be dropped.  I think PGP mode should be be dropped unless someone
specifically wants to write a PGP-compatible application.  Certainly,
implementations of the API should not be REQUIRED to support all these
modes.

    The API for OFB is obvious, but the one for CTR is considerably less so.
    My suggestion is to have the IV be the first block to be encrypted, and
    have the big/little endian issue be addressed by having CTR mean big
    endian and CLE mean little endian.

The IV for counter mode should be an int or long giving the counter
value.  CTR/CLE for endianness is ok, or just choose one endianness
and stick to it.  Are there any applications/standards with specific
endianness requirements?

Actually, I just read the PEP and it looks to me like it needs several
further changes:

  1. It says nothing about padding methods.  CBC mode should probably
  pad per RFC 1423 a/k/a PKCS #5.  I don't know about CFB mode.
  Requiring that the plaintext size be a multiple of the block size
  means there has to be another API layer to deal with padding.  That
  seems clumsy to me, but if it's what's intended, the PEP should also
  specify that layer.  I'd rather permit arbitrary lengths for
  plaintext and specify a padding algorithm.  It's best to specify how
  to do what users actually want, instead of leaving them on their own
  to code up some unspecified intermediate layer.  I.e. if you're
  going to specify a function taking a string plaintext arg and
  returning a string ciphertext, it should handle arbitrary lengths.

  2. The treatment of stream ciphers is bogus.  The idea of ECB mode for
  a stream cipher makes no sense at all.  Stream ciphers should use CTR
  or CFB mode.  They should be treated separately from block ciphers
  rather than kludged in by specifying a block size of 1.

  3. The specifications of block_size and key_size are vague: is
  "size" measured in bits, or in bytes?  The key and data args to
  the encryption function are byte strings, so block_size should
  probably be bytes (too bad for 1-bit CFB mode or 1-bit stream
  ciphers).  Usually though we think of "56-bit DES" or "128-bit AES",
  so it's slightly surprising (but ok) to have key_size be bytes.

  4. The key_size variable must be either an integer (a specific number
  of bits), or None (meaning any length at all is valid).  This doesn't
  handle AES very well--AES accepts 128, 192, or 256 bits, but not other
  values.  RC4 accepts any key length that's a multiple of 8 bits, but
  won't accept (say) 23 bits.  Maybe this variable should just be
  eliminated, and let the module throw an error if you try to set a
  key length it doesn't like.

  5. I think it should be ok to pass an initial IV of None or 0,
  equivalent to "\0"*(module.block_size) where block_size is in bytes.
  Usually you use IV=0 to compute a CBC MAC, for example.

  6. The PEP should specify what exceptions the modules can raise and when.

  7. There should be a 'mac' operation added, similar to encrypt and
  decrypt.  MAC runs the cipher and updates the IV and returns the
  final IV instead of encrypted or decrypted text.  There should also
  be a 'verify' operation which tests whether a string has a given MAC
  and returns 1 or 0.

  8. The encrypt, decrypt, mac, and verify operations should all be
  allowed to raise NotImplementedError if the cipher doesn't support
  that mode.  It's perfectly ok for a cipher to support encryption
  but not decryption, or a cipher to not support PGP chaining mode, etc.





More information about the python-crypto mailing list