Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES-CCM enforce max length #779

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/Crypto/Cipher/_mode_ccm.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,13 @@ def _start_mac(self):

# Formatting control information and nonce (A.2.1)
q = 15 - len(self.nonce) # length of Q, the encoded message length
# Limit on plaintext length imposed by choice of nonce (A.1)
if self._msg_len >= 2**(8*q):
raise OverflowError("Combined plaintext and nonce too long")
flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) +
(q - 1))
b_0 = struct.pack("B", flags) + self.nonce + long_to_bytes(self._msg_len, q)
assert len(b_0) == 16

# Formatting associated data (A.2.2)
# Encoded 'a' is concatenated with the associated data 'A'
Expand Down
13 changes: 13 additions & 0 deletions lib/Crypto/SelfTest/Cipher/test_CCM.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,19 @@ def test_shorter_ciphertext_than_declared(self):
msg_len=DATA_LEN - 1)
self.assertRaises(ValueError, cipher.decrypt, ct)

def test_plaintext_too_long_for_nonce(self):
nonce = get_tag_random("nonce", 13)
# The octet length of the binary representation of the octet length
# of the payload.
q = 15 - len(nonce)

# The plaintext must be shorter than this
# See Appendix A.1 of NIST SP 800-38C
data_len_limit = 2**(8 * q)
data = bytearray(data_len_limit)
cipher = AES.new(self.key_128, AES.MODE_CCM, nonce=nonce)
self.assertRaises(OverflowError, cipher.encrypt_and_digest, data)

def test_message_chunks(self):
# Validate that both associated data and plaintext/ciphertext
# can be broken up in chunks of arbitrary length
Expand Down
Loading