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 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]
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 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)