1# Copyright 2013 Donald Stufft and individual contributors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import nacl.bindings
16import nacl.encoding
17
18from . import _argon2
19
20ALG = _argon2.ALG_ARGON2ID13
21STRPREFIX = nacl.bindings.crypto_pwhash_argon2id_STRPREFIX
22
23SALTBYTES = _argon2.SALTBYTES
24
25PASSWD_MIN = _argon2.PASSWD_MIN
26PASSWD_MAX = _argon2.PASSWD_MAX
27
28PWHASH_SIZE = _argon2.PWHASH_SIZE
29
30BYTES_MIN = _argon2.BYTES_MIN
31BYTES_MAX = _argon2.BYTES_MAX
32
33verify = _argon2.verify
34
35MEMLIMIT_MIN = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_MIN
36MEMLIMIT_MAX = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_MAX
37OPSLIMIT_MIN = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_MIN
38OPSLIMIT_MAX = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_MAX
39
40OPSLIMIT_INTERACTIVE = (
41 nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE
42)
43MEMLIMIT_INTERACTIVE = (
44 nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE
45)
46OPSLIMIT_SENSITIVE = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE
47MEMLIMIT_SENSITIVE = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE
48
49OPSLIMIT_MODERATE = nacl.bindings.crypto_pwhash_argon2id_OPSLIMIT_MODERATE
50MEMLIMIT_MODERATE = nacl.bindings.crypto_pwhash_argon2id_MEMLIMIT_MODERATE
51
52
53def kdf(
54 size: int,
55 password: bytes,
56 salt: bytes,
57 opslimit: int = OPSLIMIT_SENSITIVE,
58 memlimit: int = MEMLIMIT_SENSITIVE,
59 encoder: nacl.encoding.Encoder = nacl.encoding.RawEncoder,
60) -> bytes:
61 """
62 Derive a ``size`` bytes long key from a caller-supplied
63 ``password`` and ``salt`` pair using the argon2id
64 memory-hard construct.
65
66 the enclosing module provides the constants
67
68 - :py:const:`.OPSLIMIT_INTERACTIVE`
69 - :py:const:`.MEMLIMIT_INTERACTIVE`
70 - :py:const:`.OPSLIMIT_MODERATE`
71 - :py:const:`.MEMLIMIT_MODERATE`
72 - :py:const:`.OPSLIMIT_SENSITIVE`
73 - :py:const:`.MEMLIMIT_SENSITIVE`
74
75 as a guidance for correct settings.
76
77 :param size: derived key size, must be between
78 :py:const:`.BYTES_MIN` and
79 :py:const:`.BYTES_MAX`
80 :type size: int
81 :param password: password used to seed the key derivation procedure;
82 it length must be between
83 :py:const:`.PASSWD_MIN` and
84 :py:const:`.PASSWD_MAX`
85 :type password: bytes
86 :param salt: **RANDOM** salt used in the key derivation procedure;
87 its length must be exactly :py:const:`.SALTBYTES`
88 :type salt: bytes
89 :param opslimit: the time component (operation count)
90 of the key derivation procedure's computational cost;
91 it must be between
92 :py:const:`.OPSLIMIT_MIN` and
93 :py:const:`.OPSLIMIT_MAX`
94 :type opslimit: int
95 :param memlimit: the memory occupation component
96 of the key derivation procedure's computational cost;
97 it must be between
98 :py:const:`.MEMLIMIT_MIN` and
99 :py:const:`.MEMLIMIT_MAX`
100 :type memlimit: int
101 :rtype: bytes
102
103 .. versionadded:: 1.2
104 """
105
106 return encoder.encode(
107 nacl.bindings.crypto_pwhash_alg(
108 size, password, salt, opslimit, memlimit, ALG
109 )
110 )
111
112
113def str(
114 password: bytes,
115 opslimit: int = OPSLIMIT_INTERACTIVE,
116 memlimit: int = MEMLIMIT_INTERACTIVE,
117) -> bytes:
118 """
119 Hashes a password with a random salt, using the memory-hard
120 argon2id construct and returning an ascii string that has all
121 the needed info to check against a future password
122
123 The default settings for opslimit and memlimit are those deemed
124 correct for the interactive user login case.
125
126 :param bytes password:
127 :param int opslimit:
128 :param int memlimit:
129 :rtype: bytes
130
131 .. versionadded:: 1.2
132 """
133 return nacl.bindings.crypto_pwhash_str_alg(
134 password, opslimit, memlimit, ALG
135 )