Source code for pyflocker.ciphers.backends.cryptography_.symmetric

"""Cryptography backend specific templates and tools for symmetric ciphers."""

from __future__ import annotations

import typing

from cryptography import exceptions as bkx

from pyflocker.ciphers import base, exc


[docs] class NonAEADCipherTemplate(base.BaseNonAEADCipher): """ Template class to provide the default behavior if BaseNonAEADCipher. Subclasses need to provide: - `_encrypting` - `_ctx` """ _encrypting: bool _ctx: typing.Any
[docs] def is_encrypting(self) -> bool: return self._encrypting
[docs] def update(self, data: bytes) -> bytes: if self._ctx is None: raise exc.AlreadyFinalized return self._ctx.update(data)
[docs] def update_into( self, data: bytes, out: bytearray | memoryview, ) -> None: if self._ctx is None: raise exc.AlreadyFinalized self._ctx.update_into(data, out)
[docs] def finalize(self) -> None: if not self._ctx: raise exc.AlreadyFinalized self._ctx = None
[docs] class AuthenticationMixin: """Mixin class to provide authentication behavior to ciphers. Classes inheriting this must provide these attributes: Attributes: _updated: A boolean indicating whether ``update()`` method of ``_cipher`` was called. _ctx: A cipher context from cryptography package that has ``finalize()`` method. _tag: A byte sequence denoting the MAC tag generated by the cipher after encryption. """ _updated: bool _ctx: typing.Any is_encrypting: typing.Callable _tag: bytes | None
[docs] def authenticate(self, data: bytes) -> None: if self._ctx is None: raise exc.AlreadyFinalized if self._updated: raise TypeError self._ctx.authenticate_additional_data(data)
[docs] def finalize(self, tag: bytes | None = None) -> None: if self._ctx is None: raise exc.AlreadyFinalized if not self.is_encrypting(): if tag is None: msg = "tag is required for finalization" raise ValueError(msg) ctx, self._ctx = self._ctx, None try: ctx.finalize_with_tag(tag) except bkx.InvalidTag as e: raise exc.DecryptionError from e else: ctx, self._ctx = self._ctx, None ctx.finalize() self._tag = ctx.tag
[docs] def calculate_tag(self) -> bytes | None: if self._ctx is not None: raise exc.NotFinalized return self._tag
[docs] class AEADCipherTemplate(AuthenticationMixin, base.BaseAEADCipher): """ Template class to provide the default behavior of BaseAEADCipher. Subclasses need to provide the following attributes: - `_encrypting` - `_ctx` """ # these are *not* class variables _updated: bool = False _tag: bytes | None = None _encrypting: bool _ctx: typing.Any
[docs] def is_encrypting(self) -> bool: return self._encrypting
[docs] def update(self, data: bytes) -> bytes: if self._ctx is None: raise exc.AlreadyFinalized self._updated = True return self._ctx.update(data)
[docs] def update_into( self, data: bytes, out: bytearray | memoryview, ) -> None: if self._ctx is None: raise exc.AlreadyFinalized self._updated = True self._ctx.update_into(data, out)