_mode_eax.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. # ===================================================================
  2. #
  3. # Copyright (c) 2014, Legrandin <helderijs@gmail.com>
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. #
  10. # 1. Redistributions of source code must retain the above copyright
  11. # notice, this list of conditions and the following disclaimer.
  12. # 2. Redistributions in binary form must reproduce the above copyright
  13. # notice, this list of conditions and the following disclaimer in
  14. # the documentation and/or other materials provided with the
  15. # distribution.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  27. # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. # POSSIBILITY OF SUCH DAMAGE.
  29. # ===================================================================
  30. """
  31. EAX mode.
  32. """
  33. __all__ = ['EaxMode']
  34. from Crypto.Util.py3compat import byte_string, bchr, bord, unhexlify, b
  35. from Crypto.Util.strxor import strxor
  36. from Crypto.Util.number import long_to_bytes, bytes_to_long
  37. from Crypto.Hash import CMAC, BLAKE2s
  38. from Crypto.Random import get_random_bytes
  39. class EaxMode(object):
  40. """*EAX* mode.
  41. This is an Authenticated Encryption with Associated Data
  42. (`AEAD`_) mode. It provides both confidentiality and authenticity.
  43. The header of the message may be left in the clear, if needed,
  44. and it will still be subject to authentication.
  45. The decryption step tells the receiver if the message comes
  46. from a source that really knowns the secret key.
  47. Additionally, decryption detects if any part of the message -
  48. including the header - has been modified or corrupted.
  49. This mode requires a *nonce*.
  50. This mode is only available for ciphers that operate on 64 or
  51. 128 bits blocks.
  52. There are no official standards defining EAX.
  53. The implementation is based on `a proposal`__ that
  54. was presented to NIST.
  55. .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
  56. .. __: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf
  57. :undocumented: __init__
  58. """
  59. def __init__(self, factory, key, nonce, mac_len, cipher_params):
  60. """EAX cipher mode"""
  61. self.block_size = factory.block_size
  62. """The block size of the underlying cipher, in bytes."""
  63. self.nonce = nonce
  64. """The nonce originally used to create the object."""
  65. self._mac_len = mac_len
  66. self._mac_tag = None # Cache for MAC tag
  67. # Allowed transitions after initialization
  68. self._next = [self.update, self.encrypt, self.decrypt,
  69. self.digest, self.verify]
  70. # MAC tag length
  71. if not (4 <= self._mac_len <= self.block_size):
  72. raise ValueError("Parameter 'mac_len' must not be larger than %d"
  73. % self.block_size)
  74. # Nonce cannot be empty and must be a byte string
  75. if len(nonce) == 0:
  76. raise ValueError("Nonce cannot be empty in EAX mode")
  77. if not byte_string(nonce):
  78. raise TypeError("Nonce must be a byte string")
  79. self._omac = [
  80. CMAC.new(key,
  81. bchr(0) * (self.block_size - 1) + bchr(i),
  82. ciphermod=factory,
  83. cipher_params=cipher_params)
  84. for i in xrange(0, 3)
  85. ]
  86. # Compute MAC of nonce
  87. self._omac[0].update(nonce)
  88. self._signer = self._omac[1]
  89. # MAC of the nonce is also the initial counter for CTR encryption
  90. counter_int = bytes_to_long(self._omac[0].digest())
  91. self._cipher = factory.new(key,
  92. factory.MODE_CTR,
  93. initial_value=counter_int,
  94. nonce=b(""),
  95. **cipher_params)
  96. def update(self, assoc_data):
  97. """Protect associated data
  98. If there is any associated data, the caller has to invoke
  99. this function one or more times, before using
  100. ``decrypt`` or ``encrypt``.
  101. By *associated data* it is meant any data (e.g. packet headers) that
  102. will not be encrypted and will be transmitted in the clear.
  103. However, the receiver is still able to detect any modification to it.
  104. If there is no associated data, this method must not be called.
  105. The caller may split associated data in segments of any size, and
  106. invoke this method multiple times, each time with the next segment.
  107. :Parameters:
  108. assoc_data : byte string
  109. A piece of associated data. There are no restrictions on its size.
  110. """
  111. if self.update not in self._next:
  112. raise TypeError("update() can only be called"
  113. " immediately after initialization")
  114. self._next = [self.update, self.encrypt, self.decrypt,
  115. self.digest, self.verify]
  116. return self._signer.update(assoc_data)
  117. def encrypt(self, plaintext):
  118. """Encrypt data with the key and the parameters set at initialization.
  119. A cipher object is stateful: once you have encrypted a message
  120. you cannot encrypt (or decrypt) another message using the same
  121. object.
  122. The data to encrypt can be broken up in two or
  123. more pieces and `encrypt` can be called multiple times.
  124. That is, the statement:
  125. >>> c.encrypt(a) + c.encrypt(b)
  126. is equivalent to:
  127. >>> c.encrypt(a+b)
  128. This function does not add any padding to the plaintext.
  129. :Parameters:
  130. plaintext : byte string
  131. The piece of data to encrypt.
  132. It can be of any length.
  133. :Return:
  134. the encrypted data, as a byte string.
  135. It is as long as *plaintext*.
  136. """
  137. if self.encrypt not in self._next:
  138. raise TypeError("encrypt() can only be called after"
  139. " initialization or an update()")
  140. self._next = [self.encrypt, self.digest]
  141. ct = self._cipher.encrypt(plaintext)
  142. self._omac[2].update(ct)
  143. return ct
  144. def decrypt(self, ciphertext):
  145. """Decrypt data with the key and the parameters set at initialization.
  146. A cipher object is stateful: once you have decrypted a message
  147. you cannot decrypt (or encrypt) another message with the same
  148. object.
  149. The data to decrypt can be broken up in two or
  150. more pieces and `decrypt` can be called multiple times.
  151. That is, the statement:
  152. >>> c.decrypt(a) + c.decrypt(b)
  153. is equivalent to:
  154. >>> c.decrypt(a+b)
  155. This function does not remove any padding from the plaintext.
  156. :Parameters:
  157. ciphertext : byte string
  158. The piece of data to decrypt.
  159. It can be of any length.
  160. :Return: the decrypted data (byte string).
  161. """
  162. if self.decrypt not in self._next:
  163. raise TypeError("decrypt() can only be called"
  164. " after initialization or an update()")
  165. self._next = [self.decrypt, self.verify]
  166. self._omac[2].update(ciphertext)
  167. return self._cipher.decrypt(ciphertext)
  168. def digest(self):
  169. """Compute the *binary* MAC tag.
  170. The caller invokes this function at the very end.
  171. This method returns the MAC that shall be sent to the receiver,
  172. together with the ciphertext.
  173. :Return: the MAC, as a byte string.
  174. """
  175. if self.digest not in self._next:
  176. raise TypeError("digest() cannot be called when decrypting"
  177. " or validating a message")
  178. self._next = [self.digest]
  179. if not self._mac_tag:
  180. tag = bchr(0) * self.block_size
  181. for i in xrange(3):
  182. tag = strxor(tag, self._omac[i].digest())
  183. self._mac_tag = tag[:self._mac_len]
  184. return self._mac_tag
  185. def hexdigest(self):
  186. """Compute the *printable* MAC tag.
  187. This method is like `digest`.
  188. :Return: the MAC, as a hexadecimal string.
  189. """
  190. return "".join(["%02x" % bord(x) for x in self.digest()])
  191. def verify(self, received_mac_tag):
  192. """Validate the *binary* MAC tag.
  193. The caller invokes this function at the very end.
  194. This method checks if the decrypted message is indeed valid
  195. (that is, if the key is correct) and it has not been
  196. tampered with while in transit.
  197. :Parameters:
  198. received_mac_tag : byte string
  199. This is the *binary* MAC, as received from the sender.
  200. :Raises MacMismatchError:
  201. if the MAC does not match. The message has been tampered with
  202. or the key is incorrect.
  203. """
  204. if self.verify not in self._next:
  205. raise TypeError("verify() cannot be called"
  206. " when encrypting a message")
  207. self._next = [self.verify]
  208. if not self._mac_tag:
  209. tag = bchr(0) * self.block_size
  210. for i in xrange(3):
  211. tag = strxor(tag, self._omac[i].digest())
  212. self._mac_tag = tag[:self._mac_len]
  213. secret = get_random_bytes(16)
  214. mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
  215. mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)
  216. if mac1.digest() != mac2.digest():
  217. raise ValueError("MAC check failed")
  218. def hexverify(self, hex_mac_tag):
  219. """Validate the *printable* MAC tag.
  220. This method is like `verify`.
  221. :Parameters:
  222. hex_mac_tag : string
  223. This is the *printable* MAC, as received from the sender.
  224. :Raises MacMismatchError:
  225. if the MAC does not match. The message has been tampered with
  226. or the key is incorrect.
  227. """
  228. self.verify(unhexlify(hex_mac_tag))
  229. def encrypt_and_digest(self, plaintext):
  230. """Perform encrypt() and digest() in one step.
  231. :Parameters:
  232. plaintext : byte string
  233. The piece of data to encrypt.
  234. :Return:
  235. a tuple with two byte strings:
  236. - the encrypted data
  237. - the MAC
  238. """
  239. return self.encrypt(plaintext), self.digest()
  240. def decrypt_and_verify(self, ciphertext, received_mac_tag):
  241. """Perform decrypt() and verify() in one step.
  242. :Parameters:
  243. ciphertext : byte string
  244. The piece of data to decrypt.
  245. received_mac_tag : byte string
  246. This is the *binary* MAC, as received from the sender.
  247. :Return: the decrypted data (byte string).
  248. :Raises MacMismatchError:
  249. if the MAC does not match. The message has been tampered with
  250. or the key is incorrect.
  251. """
  252. pt = self.decrypt(ciphertext)
  253. self.verify(received_mac_tag)
  254. return pt
  255. def _create_eax_cipher(factory, **kwargs):
  256. """Create a new block cipher, configured in EAX mode.
  257. :Parameters:
  258. factory : module
  259. A symmetric cipher module from `Crypto.Cipher` (like
  260. `Crypto.Cipher.AES`).
  261. :Keywords:
  262. key : byte string
  263. The secret key to use in the symmetric cipher.
  264. nonce : byte string
  265. A value that must never be reused for any other encryption.
  266. There are no restrictions on its length, but it is recommended to use
  267. at least 16 bytes.
  268. The nonce shall never repeat for two different messages encrypted with
  269. the same key, but it does not need to be random.
  270. If not specified, a 16 byte long random string is used.
  271. mac_len : integer
  272. Length of the MAC, in bytes. It must be no larger than the cipher
  273. block bytes (which is the default).
  274. """
  275. try:
  276. key = kwargs.pop("key")
  277. nonce = kwargs.pop("nonce", None)
  278. if nonce is None:
  279. nonce = get_random_bytes(16)
  280. mac_len = kwargs.pop("mac_len", factory.block_size)
  281. except KeyError, e:
  282. raise TypeError("Missing parameter: " + str(e))
  283. return EaxMode(factory, key, nonce, mac_len, kwargs)