summaryrefslogtreecommitdiff
path: root/lib/Crypto/Cipher/blockalgo.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Crypto/Cipher/blockalgo.py')
-rw-r--r--lib/Crypto/Cipher/blockalgo.py74
1 files changed, 57 insertions, 17 deletions
diff --git a/lib/Crypto/Cipher/blockalgo.py b/lib/Crypto/Cipher/blockalgo.py
index 0d21f44..2864f6b 100644
--- a/lib/Crypto/Cipher/blockalgo.py
+++ b/lib/Crypto/Cipher/blockalgo.py
@@ -822,7 +822,11 @@ class BlockAlgo:
res = self._cipher.decrypt(ciphertext)
return res
- if self.mode in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM):
+ if self.mode == MODE_SIV:
+ raise TypeError("decrypt() not allowed for SIV mode."
+ " Use decrypt_and_verify() instead.")
+
+ if self.mode in (MODE_CCM, MODE_EAX, MODE_GCM):
if self.decrypt not in self._next:
raise TypeError("decrypt() can only be called after initialization or an update()")
@@ -849,27 +853,11 @@ class BlockAlgo:
if self.mode == MODE_EAX:
self._omac[2].update(ciphertext)
- if self.mode == MODE_SIV:
- self._next = [self.verify]
-
- # Take the MAC and start the cipher for decryption
- self._mac = ciphertext[-self._factory.block_size:]
- self._cipher = self._siv_ctr_cipher(self._mac)
-
- # Remove MAC from ciphertext
- ciphertext = ciphertext[:-self._factory.block_size]
-
pt = self._cipher.decrypt(ciphertext)
if self.mode == MODE_CCM:
self._cipherMAC.update(pt)
- if self.mode == MODE_SIV:
- if self.nonce:
- self._cipherMAC.update(self.nonce)
- if pt:
- self._cipherMAC.update(pt)
-
return pt
def digest(self):
@@ -987,3 +975,55 @@ class BlockAlgo:
"""
self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext):
+ """Perform encrypt() and digest() in one step.
+
+ :Parameters:
+ plaintext : byte string
+ The piece of data to encrypt.
+ :Return:
+ a tuple with two byte strings:
+
+ - the encrypted data
+ - the MAC
+ """
+
+ return self.encrypt(plaintext), self.digest()
+
+ def decrypt_and_verify(self, ciphertext, mac_tag):
+ """Perform decrypt() and verify() in one step.
+
+ :Parameters:
+ ciphertext : byte string
+ The piece of data to decrypt.
+ mac_tag : byte string
+ This is the *binary* MAC, as received from the sender.
+
+ :Return: the decrypted data (byte string).
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.mode == MODE_SIV:
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() can only be called"
+ " after initialization or an update()")
+ self._next = [self.verify]
+
+ # Take the MAC and start the cipher for decryption
+ self._mac = mac_tag
+ self._cipher = self._siv_ctr_cipher(self._mac)
+
+ pt = self._cipher.decrypt(ciphertext)
+
+ if self.nonce:
+ self._cipherMAC.update(self.nonce)
+ if pt:
+ self._cipherMAC.update(pt)
+ else:
+ pt = self.decrypt(ciphertext)
+
+ self.verify(mac_tag)
+ return pt