A wrapper to present a cryptography api but use the pycryptodome module.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

71 lines
1.4 KiB

  1. from Crypto.Cipher import AES as ccAES
  2. from cryptography.exceptions import InvalidTag
  3. # https://www.pycryptodome.org/src/cipher/modern#gcm-mode
  4. class CipherEncryptor:
  5. def __init__(self, encor):
  6. self._encor = encor
  7. self.authenticate_additional_data = encor.update
  8. self.update = encor.encrypt
  9. @property
  10. def tag(self):
  11. return self._encor.digest()
  12. def finalize(self):
  13. return b''
  14. class CipherDecryptor:
  15. def __init__(self, decor, tag=None):
  16. self._decor = decor
  17. self._tag = tag
  18. self.authenticate_additional_data = decor.update
  19. self.update = decor.decrypt
  20. def finalize(self):
  21. try:
  22. #print(repr(self._decor))
  23. self._decor.verify(self._tag)
  24. except ValueError:
  25. raise InvalidTag('tag mismatch')
  26. return b''
  27. class Cipher:
  28. def __init__(self, algo, mode, backend=None):
  29. self._algo = algo
  30. self._mode = mode
  31. def _getmode(self):
  32. if isinstance(self._mode, GCM):
  33. return ccAES.MODE_GCM
  34. def _nonce(self):
  35. return self._mode._iv
  36. def encryptor(self):
  37. return CipherEncryptor(ccAES.new(self._algo._key,
  38. self._getmode(), nonce=self._nonce()))
  39. def decryptor(self):
  40. return CipherDecryptor(ccAES.new(self._algo._key,
  41. self._getmode(), nonce=self._nonce()), tag=self._mode._tag)
  42. class AES:
  43. def __init__(self, key):
  44. self._key = key
  45. class algorithms:
  46. AES = AES
  47. class GCM:
  48. def __init__(self, iv, tag=None):
  49. self._iv = iv
  50. self._tag = tag
  51. class modes:
  52. GCM = GCM