MySQL 9.7.0
Source Code Documentation
i_sha2_password.h
Go to the documentation of this file.
1/*
2Copyright (c) 2017, 2026, Oracle and/or its affiliates.
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License, version 2.0,
6as published by the Free Software Foundation.
7
8This program is designed to work with certain software (including
9but not limited to OpenSSL) that is licensed under separate terms,
10as designated in a particular file or component or in included license
11documentation. The authors of MySQL hereby grant you an additional
12permission to link the program and your derivative works with the
13separately licensed software that they have either included with
14the program or referenced in the documentation.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License, version 2.0, for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
24
25#ifndef I_SHA2_PASSWORD_INCLUDED
26#define I_SHA2_PASSWORD_INCLUDED
27
28#include <atomic>
29#include <optional>
30#include <string>
31#include <unordered_map>
32
33#include "crypt_genhash_impl.h" /* For salt, sha2 digest */
34#include "mysql/plugin.h" /* MYSQL_PLUGIN */
35#include "mysql/psi/mysql_rwlock.h" /* mysql_rwlock_t */
37
38#include <openssl/evp.h>
39
40/**
41 @file sql/auth/i_sha2_password.h
42 Classes for caching_sha2_authentication plugin
43*/
44
45/**
46 @defgroup auth_caching_sha2_auth caching_sha2_authentication information
47 @{
48*/
49
51class SHA256_digestTest;
52} // namespace sha2_password_unittest
53
54namespace sha2_password {
55/* fast digest rounds */
56const unsigned int MIN_FAST_DIGEST_ROUNDS = 2;
57const unsigned int DEFAULT_FAST_DIGEST_ROUNDS = 2;
58const unsigned int MAX_FAST_DIGEST_ROUNDS = 1000;
59
60/* Length of Digest Info field */
61const unsigned int DIGEST_INFO_LENGTH = 1;
62/* Length of iteration info field */
63const unsigned int ITERATION_LENGTH = 3;
64/* Iteration multiplier to be used on extracted iteration count */
65const unsigned int ITERATION_MULTIPLIER = 1000;
66/* Upper cap on iterations */
67const long unsigned int MAX_ITERATIONS = 0xFFF * ITERATION_MULTIPLIER;
68/* length of salt */
69const unsigned int SALT_LENGTH = CRYPT_SALT_LENGTH;
70/* $ + A + $ + ITERATION_LENGTH + $ + SALT_LENGTH + CACHING_SHA2_DIGEST_LENGTH =
71 * 59 */
72const unsigned int SHA256_AUTH_STRING_LEN =
74/* Delimiter character */
75const char DELIMITER = '$';
76/* Store digest length */
77const unsigned int STORED_SHA256_DIGEST_LENGTH = 43;
78/* stored digest rounds*/
82/* Maximum password length */
84/* Maximum supported passwords */
85const unsigned int MAX_PASSWORDS = 2;
86
87const size_t PBKDF2_DIGEST_LENGTH = SHA512_DIGEST_LENGTH;
88/*
89 Padded base64 length: 4*ceil(n/3) = 4*((n+2)/3)
90*/
92 4 * ((PBKDF2_DIGEST_LENGTH + 2) / 3);
93
94typedef struct sha2_cache_entry {
97
99
100/**
101 Password cache used for caching_sha2_authentication
102*/
103
105 public:
106 typedef std::unordered_map<std::string, sha2_cache_entry> password_cache;
107
110 bool add(const std::string &authorization_id,
111 const sha2_cache_entry &entry_to_be_cached);
112 bool remove(const std::string &authorization_id);
113 bool search(const std::string &authorization_id,
114 sha2_cache_entry &cache_entry);
115 /** Returns number of cache entries present */
116 size_t size() { return m_password_cache.size(); }
117 void clear_cache();
118
119 private:
121};
122
123/**
124 Class to handle caching_sha2_authentication
125 Provides methods for:
126 - Fast authentication
127 - Strong authentication
128 - Removal of cached entry
129*/
131 public:
133 MYSQL_PLUGIN plugin_handle, size_t stored_digest_rounds,
135 unsigned int fast_digest_rounds = DEFAULT_FAST_DIGEST_ROUNDS,
136 bool enforce_storage_format = false);
138 std::pair<bool, bool> authenticate(const std::string &authorization_id,
139 const std::string_view *serialized_string,
140 const std::string &plaintext_password,
141 bool &set_password_expired_flag);
142 std::pair<bool, bool> fast_authenticate(const std::string &authorization_id,
143 const unsigned char *random,
144 unsigned int random_length,
145 const unsigned char *scramble,
146 bool check_second);
147 void remove_cached_entry(const std::string &authorization_id);
148 bool deserialize(const std::string_view &serialized_string,
149 Stored_digest_info &digest_type, std::string &salt,
150 std::string &digest, size_t &iterations);
151 bool serialize(std::string &serialized_string,
152 const Stored_digest_info &digest_type, const std::string &salt,
153 const std::string &digest, size_t iterations);
154 bool generate_fast_digest(const std::string &plaintext_password,
155 sha2_cache_entry &digest, unsigned int loc);
156 std::pair<bool, bool> compare_against_stored(
157 const std::string &src, const std::string_view &stored,
158 const std::optional<std::string> &authorization_id,
159 Stored_digest_info &digest_type);
160 bool generate_stored_digest(const std::string &src,
161 std::string &serialized_string);
162 size_t get_cache_count();
163 void clear_cache();
164
165 bool validate_hash(const std::string &serialized_string);
166
168 return m_stored_digest_type.load();
169 }
171 m_stored_digest_type.store(digest_type);
172 clear_cache();
173 }
174
176 void set_stored_digest_rounds(size_t stored_digest_rounds) {
177 m_stored_digest_rounds.store(stored_digest_rounds);
178 clear_cache();
179 }
180
184 clear_cache();
185 }
186
187 unsigned int get_fast_digest_rounds() { return m_fast_digest_rounds.load(); }
188
190
191 protected:
192 bool generate_crypt5(const std::string &source, const std::string &salt,
193 std::string &digest, unsigned int iterations);
194 bool generate_pbkdf2(const std::string &source, const std::string &salt,
195 std::string &digest, unsigned int iterations);
196
197 private:
198 /** Plugin handle */
200 /** Number of rounds for stored digest */
201 std::atomic<size_t> m_stored_digest_rounds;
202 /** Stored digest type */
203 std::atomic<Stored_digest_info> m_stored_digest_type;
204 /** Number of rounds for fast digest */
205 std::atomic_uint m_fast_digest_rounds;
206 /** Lock to protect @c m_cache */
208 /** user=>password cache */
210 /* Enforce storage format */
211 std::atomic_bool m_enforce_storage_format;
212};
213} // namespace sha2_password
214
215/** @} (end of auth_caching_sha2_auth) */
216
217#endif // !I_SHA2_PASSWORD_INCLUDED
Class to handle caching_sha2_authentication Provides methods for:
Definition: i_sha2_password.h:130
std::atomic_uint m_fast_digest_rounds
Number of rounds for fast digest.
Definition: i_sha2_password.h:205
Caching_sha2_password(MYSQL_PLUGIN plugin_handle, size_t stored_digest_rounds, Stored_digest_info digest_type=Stored_digest_info::CRYPT5, unsigned int fast_digest_rounds=DEFAULT_FAST_DIGEST_ROUNDS, bool enforce_storage_format=false)
Caching_sha2_password constructor - Initializes rw lock.
Definition: sha2_password.cc:207
size_t get_cache_count()
Get cache count.
Definition: sha2_password.cc:864
SHA2_password_cache m_cache
user=>password cache
Definition: i_sha2_password.h:209
void remove_cached_entry(const std::string &authorization_id)
Remove an entry from the cache.
Definition: sha2_password.cc:467
Stored_digest_info get_stored_digest_type() const
Definition: i_sha2_password.h:167
bool get_enforce_storage_format()
Definition: i_sha2_password.h:181
std::pair< bool, bool > compare_against_stored(const std::string &src, const std::string_view &stored, const std::optional< std::string > &authorization_id, Stored_digest_info &digest_type)
Definition: sha2_password.cc:249
std::pair< bool, bool > fast_authenticate(const std::string &authorization_id, const unsigned char *random, unsigned int random_length, const unsigned char *scramble, bool check_second)
Perform fast authentication.
Definition: sha2_password.cc:420
friend class sha2_password_unittest::SHA256_digestTest
Definition: i_sha2_password.h:189
mysql_rwlock_t m_cache_lock
Lock to protect m_cache.
Definition: i_sha2_password.h:207
void clear_cache()
Clear the password cache.
Definition: sha2_password.cc:871
bool generate_fast_digest(const std::string &plaintext_password, sha2_cache_entry &digest, unsigned int loc)
Generate digest based on get_fast_digest_rounds()
Definition: sha2_password.cc:687
size_t get_stored_digest_rounds()
Definition: i_sha2_password.h:175
unsigned int get_fast_digest_rounds()
Definition: i_sha2_password.h:187
std::atomic< size_t > m_stored_digest_rounds
Number of rounds for stored digest.
Definition: i_sha2_password.h:201
bool serialize(std::string &serialized_string, const Stored_digest_info &digest_type, const std::string &salt, const std::string &digest, size_t iterations)
Serialize following: a.
Definition: sha2_password.cc:619
void set_stored_digest_type(Stored_digest_info digest_type)
Definition: i_sha2_password.h:170
void set_enforce_storage_format(bool value)
Definition: i_sha2_password.h:182
bool deserialize(const std::string_view &serialized_string, Stored_digest_info &digest_type, std::string &salt, std::string &digest, size_t &iterations)
Deserialize obtained hash and retrieve various parts.
Definition: sha2_password.cc:509
bool generate_stored_digest(const std::string &src, std::string &serialized_string)
Definition: sha2_password.cc:824
~Caching_sha2_password()
Caching_sha2_password destructor - destroy rw lock.
Definition: sha2_password.cc:233
bool generate_pbkdf2(const std::string &source, const std::string &salt, std::string &digest, unsigned int iterations)
Transform given password into PKBDF2 digest.
Definition: sha2_password.cc:769
bool generate_crypt5(const std::string &source, const std::string &salt, std::string &digest, unsigned int iterations)
Generate multi-round sha2 hash using source and random string.
Definition: sha2_password.cc:737
bool validate_hash(const std::string &serialized_string)
Validate a hash format.
Definition: sha2_password.cc:886
MYSQL_PLUGIN m_plugin_info
Plugin handle.
Definition: i_sha2_password.h:199
std::pair< bool, bool > authenticate(const std::string &authorization_id, const std::string_view *serialized_string, const std::string &plaintext_password, bool &set_password_expired_flag)
Perform slow authentication.
Definition: sha2_password.cc:330
void set_stored_digest_rounds(size_t stored_digest_rounds)
Definition: i_sha2_password.h:176
std::atomic_bool m_enforce_storage_format
Definition: i_sha2_password.h:211
std::atomic< Stored_digest_info > m_stored_digest_type
Stored digest type.
Definition: i_sha2_password.h:203
Password cache used for caching_sha2_authentication.
Definition: i_sha2_password.h:104
password_cache m_password_cache
Definition: i_sha2_password.h:120
bool search(const std::string &authorization_id, sha2_cache_entry &cache_entry)
Search an entry from the cache.
Definition: sha2_password.cc:170
size_t size()
Returns number of cache entries present
Definition: i_sha2_password.h:116
bool remove(const std::string &authorization_id)
Remove an entry from the cache.
Definition: sha2_password.cc:147
void clear_cache()
Clear the cache - Release all memory.
Definition: sha2_password.cc:186
bool add(const std::string &authorization_id, const sha2_cache_entry &entry_to_be_cached)
Add an entry in cache We manage our own memory.
Definition: sha2_password.cc:130
std::unordered_map< std::string, sha2_cache_entry > password_cache
Definition: i_sha2_password.h:106
#define MAX_PLAINTEXT_LENGTH
Definition: crypt_genhash_impl.h:49
#define CRYPT_SALT_LENGTH
Definition: crypt_genhash_impl.h:42
#define SHA2_ROUNDS_MAX
Definition: crypt_genhash_impl.h:39
#define SHA2_ROUNDS_MIN
Definition: crypt_genhash_impl.h:38
#define SHA2_ROUNDS_DEFAULT
Definition: crypt_genhash_impl.h:37
Classes for caching_sha2_authentication plugin.
void * MYSQL_PLUGIN
Definition: plugin.h:84
void scramble(char *to, const char *message, const char *password)
Produce an obscure octet sequence from password and random string, received from the server.
Definition: mysql_native_password.cc:176
static unsigned int iterations
Definition: mysqlslap.cc:190
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
Definition: i_sha2_password.h:50
Definition: i_sha2_password.h:54
const unsigned int DIGEST_INFO_LENGTH
Definition: i_sha2_password.h:61
const unsigned int CACHING_SHA2_DIGEST_LENGTH
Definition: i_sha2_password_common.h:45
const size_t PBKDF2_DIGEST_LENGTH
Definition: i_sha2_password.h:87
const char DELIMITER
Definition: i_sha2_password.h:75
const unsigned int STORED_SHA256_DIGEST_LENGTH
Definition: i_sha2_password.h:77
const unsigned int ITERATION_LENGTH
Definition: i_sha2_password.h:63
const long unsigned int MAX_ITERATIONS
Definition: i_sha2_password.h:67
const size_t CACHING_SHA2_PASSWORD_MAX_PASSWORD_LENGTH
Definition: i_sha2_password.h:83
const unsigned int MAX_FAST_DIGEST_ROUNDS
Definition: i_sha2_password.h:58
struct sha2_password::sha2_cache_entry sha2_cache_entry
const unsigned int DEFAULT_FAST_DIGEST_ROUNDS
Definition: i_sha2_password.h:57
const size_t MAX_STORED_DIGEST_ROUNDS
Definition: i_sha2_password.h:81
const size_t DEFAULT_STORED_DIGEST_ROUNDS
Definition: i_sha2_password.h:80
const unsigned int MIN_FAST_DIGEST_ROUNDS
Definition: i_sha2_password.h:56
constexpr size_t STORED_PBKDF2_DIGEST_LENGTH
Definition: i_sha2_password.h:91
const unsigned int MAX_PASSWORDS
Definition: i_sha2_password.h:85
const unsigned int SHA256_AUTH_STRING_LEN
Definition: i_sha2_password.h:72
Stored_digest_info
Definition: i_sha2_password.h:98
const size_t MIN_STORED_DIGEST_ROUNDS
Definition: i_sha2_password.h:79
const unsigned int ITERATION_MULTIPLIER
Definition: i_sha2_password.h:65
const unsigned int SALT_LENGTH
Definition: i_sha2_password.h:69
Instrumentation helpers for rwlock.
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
An instrumented rwlock structure.
Definition: mysql_rwlock_bits.h:51
Definition: i_sha2_password.h:94
unsigned char digest_buffer[MAX_PASSWORDS][CACHING_SHA2_DIGEST_LENGTH]
Definition: i_sha2_password.h:95