Skip to content

Commit c4f34a2

Browse files
Add Support for Argon2d and Argon2i Variants (#13715)
* Adding test vectors for argon2d and argon2i variants * Initial support backend for Argon2d and Argon2i variants - Adding python class stubs * Updating pytests to cover Argon2d and Argon2i variants * - Modify type hints to support py3.8 - Scope Argon2Variant enum to OpenSSL >=3.2 * Updating docs for Argon2 family * Correcting typos * Rename base attribute and remove "allow(unused)" tag * Correct "versionadded" docstring for Argon2d and Argon2i * Update error message to include helpful hint when using wrong Argon2 class * Update unit tests to exercise all Argon2 variants for derive_into * Removing empty spacing to appease ruff * Add derive_into interface definitions for additional Argon2 variants
1 parent 3edc452 commit c4f34a2

File tree

5 files changed

+529
-103
lines changed

5 files changed

+529
-103
lines changed

docs/hazmat/primitives/key-derivation-functions.rst

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,36 @@ Different KDFs are suitable for different tasks such as:
3030
Variable cost algorithms
3131
~~~~~~~~~~~~~~~~~~~~~~~~
3232

33-
Argon2id
34-
--------
33+
Argon2 Family
34+
-------------
3535

3636
.. currentmodule:: cryptography.hazmat.primitives.kdf.argon2
3737

38+
The Argon2 family of key derivation functions are designed for password storage and is described in :rfc:`9106`.
39+
It consists of three variants that differ only how they access an internal memory buffer, which leads to different
40+
trade-offs in resistance to hardware attacks.
41+
42+
Each of the classes constructors and parameters are the same; only details of Argon2id are defined before, for brevity.
43+
44+
.. class:: Argon2d(*, salt, length, iterations, lanes, memory_cost, ad=None, secret=None)
45+
46+
.. versionadded:: 47.0.0
47+
48+
This variant of the Argon2 family maximizes resistance to time-memory-trade-off attacks, but introduces possible side-channels
49+
50+
51+
.. class:: Argon2i(*, salt, length, iterations, lanes, memory_cost, ad=None, secret=None)
52+
53+
.. versionadded:: 47.0.0
54+
55+
This variant of the Argon2 family resists side-channel attacks, but is vulnerable to time-memory-trade-off attacks
56+
57+
3858
.. class:: Argon2id(*, salt, length, iterations, lanes, memory_cost, ad=None, secret=None)
3959

4060
.. versionadded:: 44.0.0
4161

42-
Argon2id is a KDF designed for password storage. It is designed to be
43-
resistant to hardware attacks and is described in :rfc:`9106`.
62+
Argon2id is a blend of the previous two variants. Argon2id should be used by most users, as recommended in :rfc:`9106`.
4463

4564
This class conforms to the
4665
:class:`~cryptography.hazmat.primitives.kdf.KeyDerivationFunction`

src/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,48 @@ class Scrypt:
3434
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
3535
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
3636

37+
class Argon2d:
38+
def __init__(
39+
self,
40+
*,
41+
salt: bytes,
42+
length: int,
43+
iterations: int,
44+
lanes: int,
45+
memory_cost: int,
46+
ad: bytes | None = None,
47+
secret: bytes | None = None,
48+
) -> None: ...
49+
def derive(self, key_material: bytes) -> bytes: ...
50+
def derive_into(self, key_material: bytes, buffer: Buffer) -> int: ...
51+
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
52+
def derive_phc_encoded(self, key_material: bytes) -> str: ...
53+
@classmethod
54+
def verify_phc_encoded(
55+
cls, key_material: bytes, phc_encoded: str, secret: bytes | None = None
56+
) -> None: ...
57+
58+
class Argon2i:
59+
def __init__(
60+
self,
61+
*,
62+
salt: bytes,
63+
length: int,
64+
iterations: int,
65+
lanes: int,
66+
memory_cost: int,
67+
ad: bytes | None = None,
68+
secret: bytes | None = None,
69+
) -> None: ...
70+
def derive(self, key_material: bytes) -> bytes: ...
71+
def derive_into(self, key_material: bytes, buffer: Buffer) -> int: ...
72+
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
73+
def derive_phc_encoded(self, key_material: bytes) -> str: ...
74+
@classmethod
75+
def verify_phc_encoded(
76+
cls, key_material: bytes, phc_encoded: str, secret: bytes | None = None
77+
) -> None: ...
78+
3779
class Argon2id:
3880
def __init__(
3981
self,

src/cryptography/hazmat/primitives/kdf/argon2.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
88
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
99

10+
Argon2d = rust_openssl.kdf.Argon2d
11+
Argon2i = rust_openssl.kdf.Argon2i
1012
Argon2id = rust_openssl.kdf.Argon2id
13+
KeyDerivationFunction.register(Argon2d)
14+
KeyDerivationFunction.register(Argon2i)
1115
KeyDerivationFunction.register(Argon2id)
1216

13-
__all__ = ["Argon2id"]
17+
__all__ = ["Argon2d", "Argon2i", "Argon2id"]

0 commit comments

Comments
 (0)