Skip to content

Commit 2d62c51

Browse files
committed
Use TryComputeHash to remove more allocations.
1 parent 26f91f1 commit 2d62c51

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

src/MySqlConnector/Core/ServerSession.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ private async Task<PayloadData> SwitchAuthenticationAsync(ConnectionSettings cs,
580580
return await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
581581

582582
case "caching_sha2_password":
583-
var scrambleBytes = AuthenticationUtility.CreateScrambleResponse(Utility.TrimZeroByte(switchRequest.Data), cs.Password);
583+
var scrambleBytes = AuthenticationUtility.CreateScrambleResponse(Utility.TrimZeroByte(switchRequest.Data.AsSpan()), cs.Password);
584584
payload = new PayloadData(scrambleBytes);
585585
await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false);
586586
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);

src/MySqlConnector/Protocol/Serialization/AuthenticationUtility.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ public static byte[] HashPassword(ReadOnlySpan<byte> challenge, string password)
2323
Span<byte> combined = stackalloc byte[40];
2424
challenge.CopyTo(combined);
2525

26-
var passwordBytes = Encoding.UTF8.GetBytes(password);
26+
var passwordByteCount = Encoding.UTF8.GetByteCount(password);
27+
Span<byte> passwordBytes = stackalloc byte[passwordByteCount];
28+
Encoding.UTF8.GetBytes(password.AsSpan(), passwordBytes);
2729
Span<byte> hashedPassword = stackalloc byte[20];
2830
sha1.TryComputeHash(passwordBytes, hashedPassword, out _);
2931
sha1.TryComputeHash(hashedPassword, combined.Slice(20), out _);
@@ -36,7 +38,7 @@ public static byte[] HashPassword(ReadOnlySpan<byte> challenge, string password)
3638
return hashedPassword.ToArray();
3739
}
3840

39-
public static byte[] CreateScrambleResponse(byte[] nonce, string password)
41+
public static byte[] CreateScrambleResponse(ReadOnlySpan<byte> nonce, string password)
4042
{
4143
var scrambleResponse = string.IsNullOrEmpty(password)
4244
? Utility.EmptyByteArray
@@ -45,23 +47,26 @@ public static byte[] CreateScrambleResponse(byte[] nonce, string password)
4547
return scrambleResponse;
4648
}
4749

48-
private static byte[] HashPasswordWithNonce(byte[] nonce, string password)
50+
private static byte[] HashPasswordWithNonce(ReadOnlySpan<byte> nonce, string password)
4951
{
5052
using var sha256 = SHA256.Create();
51-
var passwordBytes = Encoding.UTF8.GetBytes(password);
52-
var hashedPassword = sha256.ComputeHash(passwordBytes);
53+
var passwordByteCount = Encoding.UTF8.GetByteCount(password);
54+
Span<byte> passwordBytes = stackalloc byte[passwordByteCount];
55+
Encoding.UTF8.GetBytes(password.AsSpan(), passwordBytes);
5356

54-
var doubleHashedPassword = sha256.ComputeHash(hashedPassword);
55-
var combined = new byte[doubleHashedPassword.Length + nonce.Length];
57+
Span<byte> hashedPassword = stackalloc byte[32];
58+
sha256.TryComputeHash(passwordBytes, hashedPassword, out _);
5659

57-
Buffer.BlockCopy(doubleHashedPassword, 0, combined, 0, doubleHashedPassword.Length);
58-
Buffer.BlockCopy(nonce, 0, combined, doubleHashedPassword.Length, nonce.Length);
60+
Span<byte> combined = stackalloc byte[32 + nonce.Length];
61+
sha256.TryComputeHash(hashedPassword, combined, out _);
62+
nonce.CopyTo(combined.Slice(32));
5963

60-
var xorBytes = sha256.ComputeHash(combined);
64+
Span<byte> xorBytes = stackalloc byte[32];
65+
sha256.TryComputeHash(combined, xorBytes, out _);
6166
for (int i = 0; i < hashedPassword.Length; i++)
6267
hashedPassword[i] ^= xorBytes[i];
6368

64-
return hashedPassword;
69+
return hashedPassword.ToArray();
6570
}
6671
}
6772
}

src/MySqlConnector/Utilities/Utility.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ public static byte[] TrimZeroByte(byte[] value)
391391
return value;
392392
}
393393

394+
public static ReadOnlySpan<byte> TrimZeroByte(ReadOnlySpan<byte> value) =>
395+
value[value.Length - 1] == 0 ? value.Slice(0, value.Length - 1) : value;
396+
394397
#if NET45
395398
public static bool TryGetBuffer(this MemoryStream memoryStream, out ArraySegment<byte> buffer)
396399
{

0 commit comments

Comments
 (0)