OCB-AES implementation in pure Python

2010-01-20 00:00:00 +0000


This module provides pure Python implementation of authenticated encryption mode OCB (Offset Codebook Mode) using AES block cipher. OCB offers confidentiality, integrity and authenticity of data in single encryption step and using single interface. It’s alternative to traditional modes (like CTR or CBC) with separate HMAC calculation. Download ————

Data representation

The module operates on bytearray objects. Key, nonce, header and plaintext should be passed to OCB as bytearrays.

>>> plaintext = bytearray('The Magic Words are Squeamish Ossifrage')
>>> header = bytearray('Recipient: john.doe@example.com')
>>> key = bytearray().fromhex('A45F5FDEA5C088D1D7C8BE37CABC8C5C')
>>> nonce = bytearray(range(16))

Loading

Load a block cipher and OCB mode:

>>> from ocb.aes import AES
>>> from ocb import OCB

The OCB module provides built-in AES implementation, but other block ciphers can be used as well.

Initalize OCB-AES cipher objects:

>>> aes = AES(128)
>>> ocb = OCB(aes)

Parameters

OCB has two parameters: key and nonce. Key will be typically 128 bit AES key:

>>> key = bytearray().fromhex('A45F5FDEA5C088D1D7C8BE37CABC8C5C')
>>> ocb.setKey(key)

Nonce must be selected as a new value for each message encrypted. Nonce has to be the same length as key:

>>> nonce = bytearray(range(16))
>>> ocb.setNonce(nonce)

Encryption

Input plaintext of arbitrary length. This block will be encrypted and its integrity protected:

>>> plaintext = bytearray('The Magic Words are Squeamish Ossifrage')

Optional, plaintext header of arbitrary length. This block will not be encrypted, but its integrity will be protected:

>>> header = bytearray('Recipient: john.doe@example.com')

Encryption method over plaintext and header returns ciphertext and authentication tag. The tag protects integrity of both plaintext and header.

>>> (tag,ciphertext) = ocb.encrypt(plaintext, header)
>>> tag
bytearray(b')\xc9vx\xda\xc9Z\x80)\xfe@\xd9)\x8d\x86\x91')
>>> ciphertext
bytearray(b'3D\xdf\x01\xf3;\xe8\x87\x84@\xef\xac\xbcyK:J_3} \x9e\x889\xcd\xa4NvW\x88\xc1}5\x9a\x8b\xc3\x82\xd9Z')

Decryption

The decrypt method takes header, ciphertext and tag on input. It returns a tuple of decrypted plaintext and flag indicating whether input data was not tampered with.

>>> (is_authentic, plaintext2) = ocb.decrypt(header, ciphertext, tag)
>>> is_authentic
True
>>> str(plaintext2)
'The Magic Words are Squeamish Ossifrage'

If ciphertext is tampered with, the flag will be set to False and plaintext will be empty :

>>> ciphertext[3] = 0      # here I tamper with ciphertext
>>> ocb.decrypt(header, ciphertext, tag)
(False, [])

The same happens if header is modified (even if ciphertext was not):

>>> header[3] = 0         # here I tamper with header
>>> ocb.decrypt(header, ciphertext, tag)
(False, [])

References