aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst')
-rw-r--r--roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst244
1 files changed, 244 insertions, 0 deletions
diff --git a/roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst b/roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst
new file mode 100644
index 000000000..9b95621ef
--- /dev/null
+++ b/roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography/docs/fernet.rst
@@ -0,0 +1,244 @@
+Fernet (symmetric encryption)
+=============================
+
+.. currentmodule:: cryptography.fernet
+
+Fernet guarantees that a message encrypted using it cannot be
+manipulated or read without the key. `Fernet`_ is an implementation of
+symmetric (also known as "secret key") authenticated cryptography. Fernet also
+has support for implementing key rotation via :class:`MultiFernet`.
+
+.. class:: Fernet(key)
+
+ This class provides both encryption and decryption facilities.
+
+ .. doctest::
+
+ >>> from cryptography.fernet import Fernet
+ >>> key = Fernet.generate_key()
+ >>> f = Fernet(key)
+ >>> token = f.encrypt(b"my deep dark secret")
+ >>> token
+ b'...'
+ >>> f.decrypt(token)
+ b'my deep dark secret'
+
+ :param bytes key: A URL-safe base64-encoded 32-byte key. This **must** be
+ kept secret. Anyone with this key is able to create and
+ read messages.
+
+ .. classmethod:: generate_key()
+
+ Generates a fresh fernet key. Keep this some place safe! If you lose it
+ you'll no longer be able to decrypt messages; if anyone else gains
+ access to it, they'll be able to decrypt all of your messages, and
+ they'll also be able forge arbitrary messages that will be
+ authenticated and decrypted.
+
+ .. method:: encrypt(data)
+
+ Encrypts data passed. The result of this encryption is known as a
+ "Fernet token" and has strong privacy and authenticity guarantees.
+
+ :param bytes data: The message you would like to encrypt.
+ :returns bytes: A secure message that cannot be read or altered
+ without the key. It is URL-safe base64-encoded. This is
+ referred to as a "Fernet token".
+ :raises TypeError: This exception is raised if ``data`` is not
+ ``bytes``.
+
+ .. note::
+
+ The encrypted message contains the current time when it was
+ generated in *plaintext*, the time a message was created will
+ therefore be visible to a possible attacker.
+
+ .. method:: decrypt(token, ttl=None)
+
+ Decrypts a Fernet token. If successfully decrypted you will receive the
+ original plaintext as the result, otherwise an exception will be
+ raised. It is safe to use this data immediately as Fernet verifies
+ that the data has not been tampered with prior to returning it.
+
+ :param bytes token: The Fernet token. This is the result of calling
+ :meth:`encrypt`.
+ :param int ttl: Optionally, the number of seconds old a message may be
+ for it to be valid. If the message is older than
+ ``ttl`` seconds (from the time it was originally
+ created) an exception will be raised. If ``ttl`` is not
+ provided (or is ``None``), the age of the message is
+ not considered.
+ :returns bytes: The original plaintext.
+ :raises cryptography.fernet.InvalidToken: If the ``token`` is in any
+ way invalid, this exception
+ is raised. A token may be
+ invalid for a number of
+ reasons: it is older than the
+ ``ttl``, it is malformed, or
+ it does not have a valid
+ signature.
+ :raises TypeError: This exception is raised if ``token`` is not
+ ``bytes``.
+
+ .. method:: extract_timestamp(token)
+
+ .. versionadded:: 2.3
+
+ Returns the timestamp for the token. The caller can then decide if
+ the token is about to expire and, for example, issue a new token.
+
+ :param bytes token: The Fernet token. This is the result of calling
+ :meth:`encrypt`.
+ :returns int: The UNIX timestamp of the token.
+ :raises cryptography.fernet.InvalidToken: If the ``token``'s signature
+ is invalid this exception
+ is raised.
+ :raises TypeError: This exception is raised if ``token`` is not
+ ``bytes``.
+
+
+.. class:: MultiFernet(fernets)
+
+ .. versionadded:: 0.7
+
+ This class implements key rotation for Fernet. It takes a ``list`` of
+ :class:`Fernet` instances and implements the same API with the exception
+ of one additional method: :meth:`MultiFernet.rotate`:
+
+ .. doctest::
+
+ >>> from cryptography.fernet import Fernet, MultiFernet
+ >>> key1 = Fernet(Fernet.generate_key())
+ >>> key2 = Fernet(Fernet.generate_key())
+ >>> f = MultiFernet([key1, key2])
+ >>> token = f.encrypt(b"Secret message!")
+ >>> token
+ b'...'
+ >>> f.decrypt(token)
+ b'Secret message!'
+
+ MultiFernet performs all encryption options using the *first* key in the
+ ``list`` provided. MultiFernet attempts to decrypt tokens with each key in
+ turn. A :class:`cryptography.fernet.InvalidToken` exception is raised if
+ the correct key is not found in the ``list`` provided.
+
+ Key rotation makes it easy to replace old keys. You can add your new key at
+ the front of the list to start encrypting new messages, and remove old keys
+ as they are no longer needed.
+
+ Token rotation as offered by :meth:`MultiFernet.rotate` is a best practice
+ and manner of cryptographic hygiene designed to limit damage in the event of
+ an undetected event and to increase the difficulty of attacks. For example,
+ if an employee who had access to your company's fernet keys leaves, you'll
+ want to generate new fernet key, rotate all of the tokens currently deployed
+ using that new key, and then retire the old fernet key(s) to which the
+ employee had access.
+
+ .. method:: rotate(msg)
+
+ .. versionadded:: 2.2
+
+ Rotates a token by re-encrypting it under the :class:`MultiFernet`
+ instance's primary key. This preserves the timestamp that was originally
+ saved with the token. If a token has successfully been rotated then the
+ rotated token will be returned. If rotation fails this will raise an
+ exception.
+
+ .. doctest::
+
+ >>> from cryptography.fernet import Fernet, MultiFernet
+ >>> key1 = Fernet(Fernet.generate_key())
+ >>> key2 = Fernet(Fernet.generate_key())
+ >>> f = MultiFernet([key1, key2])
+ >>> token = f.encrypt(b"Secret message!")
+ >>> token
+ b'...'
+ >>> f.decrypt(token)
+ b'Secret message!'
+ >>> key3 = Fernet(Fernet.generate_key())
+ >>> f2 = MultiFernet([key3, key1, key2])
+ >>> rotated = f2.rotate(token)
+ >>> f2.decrypt(rotated)
+ b'Secret message!'
+
+ :param bytes msg: The token to re-encrypt.
+ :returns bytes: A secure message that cannot be read or altered without
+ the key. This is URL-safe base64-encoded. This is referred to as a
+ "Fernet token".
+ :raises cryptography.fernet.InvalidToken: If a ``token`` is in any
+ way invalid this exception is raised.
+ :raises TypeError: This exception is raised if the ``msg`` is not
+ ``bytes``.
+
+
+.. class:: InvalidToken
+
+ See :meth:`Fernet.decrypt` for more information.
+
+
+Using passwords with Fernet
+---------------------------
+
+It is possible to use passwords with Fernet. To do this, you need to run the
+password through a key derivation function such as
+:class:`~cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC`, bcrypt or
+:class:`~cryptography.hazmat.primitives.kdf.scrypt.Scrypt`.
+
+.. doctest::
+
+ >>> import base64
+ >>> import os
+ >>> from cryptography.fernet import Fernet
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
+ >>> password = b"password"
+ >>> salt = os.urandom(16)
+ >>> kdf = PBKDF2HMAC(
+ ... algorithm=hashes.SHA256(),
+ ... length=32,
+ ... salt=salt,
+ ... iterations=100000,
+ ... backend=default_backend()
+ ... )
+ >>> key = base64.urlsafe_b64encode(kdf.derive(password))
+ >>> f = Fernet(key)
+ >>> token = f.encrypt(b"Secret message!")
+ >>> token
+ b'...'
+ >>> f.decrypt(token)
+ b'Secret message!'
+
+In this scheme, the salt has to be stored in a retrievable location in order
+to derive the same key from the password in the future.
+
+The iteration count used should be adjusted to be as high as your server can
+tolerate. A good default is at least 100,000 iterations which is what Django
+recommended in 2014.
+
+Implementation
+--------------
+
+Fernet is built on top of a number of standard cryptographic primitives.
+Specifically it uses:
+
+* :class:`~cryptography.hazmat.primitives.ciphers.algorithms.AES` in
+ :class:`~cryptography.hazmat.primitives.ciphers.modes.CBC` mode with a
+ 128-bit key for encryption; using
+ :class:`~cryptography.hazmat.primitives.padding.PKCS7` padding.
+* :class:`~cryptography.hazmat.primitives.hmac.HMAC` using
+ :class:`~cryptography.hazmat.primitives.hashes.SHA256` for authentication.
+* Initialization vectors are generated using ``os.urandom()``.
+
+For complete details consult the `specification`_.
+
+Limitations
+-----------
+
+Fernet is ideal for encrypting data that easily fits in memory. As a design
+feature it does not expose unauthenticated bytes. Unfortunately, this makes it
+generally unsuitable for very large files at this time.
+
+
+.. _`Fernet`: https://github.com/fernet/spec/
+.. _`specification`: https://github.com/fernet/spec/blob/master/Spec.md