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_ARGON2I13
21STRPREFIX = nacl.bindings.crypto_pwhash_argon2i_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_MAX = nacl.bindings.crypto_pwhash_argon2i_MEMLIMIT_MAX
36MEMLIMIT_MIN = nacl.bindings.crypto_pwhash_argon2i_MEMLIMIT_MIN
37OPSLIMIT_MAX = nacl.bindings.crypto_pwhash_argon2i_OPSLIMIT_MAX
38OPSLIMIT_MIN = nacl.bindings.crypto_pwhash_argon2i_OPSLIMIT_MIN
39
40OPSLIMIT_INTERACTIVE = nacl.bindings.crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE
41MEMLIMIT_INTERACTIVE = nacl.bindings.crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE
42OPSLIMIT_SENSITIVE = nacl.bindings.crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE
43MEMLIMIT_SENSITIVE = nacl.bindings.crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE
44
45OPSLIMIT_MODERATE = nacl.bindings.crypto_pwhash_argon2i_OPSLIMIT_MODERATE
46MEMLIMIT_MODERATE = nacl.bindings.crypto_pwhash_argon2i_MEMLIMIT_MODERATE
47
48
49def kdf(
50 size: int,
51 password: bytes,
52 salt: bytes,
53 opslimit: int = OPSLIMIT_SENSITIVE,
54 memlimit: int = MEMLIMIT_SENSITIVE,
55 encoder: nacl.encoding.Encoder = nacl.encoding.RawEncoder,
56) -> bytes:
57 """
58 Derive a ``size`` bytes long key from a caller-supplied
59 ``password`` and ``salt`` pair using the argon2i
60 memory-hard construct.
61
62 the enclosing module provides the constants
63
64 - :py:const:`.OPSLIMIT_INTERACTIVE`
65 - :py:const:`.MEMLIMIT_INTERACTIVE`
66 - :py:const:`.OPSLIMIT_MODERATE`
67 - :py:const:`.MEMLIMIT_MODERATE`
68 - :py:const:`.OPSLIMIT_SENSITIVE`
69 - :py:const:`.MEMLIMIT_SENSITIVE`
70
71 as a guidance for correct settings.
72
73 :param size: derived key size, must be between
74 :py:const:`.BYTES_MIN` and
75 :py:const:`.BYTES_MAX`
76 :type size: int
77 :param password: password used to seed the key derivation procedure;
78 it length must be between
79 :py:const:`.PASSWD_MIN` and
80 :py:const:`.PASSWD_MAX`
81 :type password: bytes
82 :param salt: **RANDOM** salt used in the key derivation procedure;
83 its length must be exactly :py:const:`.SALTBYTES`
84 :type salt: bytes
85 :param opslimit: the time component (operation count)
86 of the key derivation procedure's computational cost;
87 it must be between
88 :py:const:`.OPSLIMIT_MIN` and
89 :py:const:`.OPSLIMIT_MAX`
90 :type opslimit: int
91 :param memlimit: the memory occupation component
92 of the key derivation procedure's computational cost;
93 it must be between
94 :py:const:`.MEMLIMIT_MIN` and
95 :py:const:`.MEMLIMIT_MAX`
96 :type memlimit: int
97 :rtype: bytes
98
99 .. versionadded:: 1.2
100 """
101
102 return encoder.encode(
103 nacl.bindings.crypto_pwhash_alg(
104 size, password, salt, opslimit, memlimit, ALG
105 )
106 )
107
108
109def str(
110 password: bytes,
111 opslimit: int = OPSLIMIT_INTERACTIVE,
112 memlimit: int = MEMLIMIT_INTERACTIVE,
113) -> bytes:
114 """
115 Hashes a password with a random salt, using the memory-hard
116 argon2i construct and returning an ascii string that has all
117 the needed info to check against a future password
118
119
120 The default settings for opslimit and memlimit are those deemed
121 correct for the interactive user login case.
122
123 :param bytes password:
124 :param int opslimit:
125 :param int memlimit:
126 :rtype: bytes
127
128 .. versionadded:: 1.2
129 """
130 return nacl.bindings.crypto_pwhash_str_alg(
131 password, opslimit, memlimit, ALG
132 )