Skip to content

Commit 44c7b05

Browse files
authored
Make SASL faster (#553)
1 parent d2d8a38 commit 44c7b05

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

Sources/PostgresNIO/Utilities/SASLAuthentication+SCRAM-SHA256.swift

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ internal struct SHA256: SASLAuthenticationMechanism {
292292
/// authenticating user. If the closure throws, authentication
293293
/// immediately fails with the thrown error.
294294
internal init(username: String, password: @escaping () throws -> String) {
295-
self._impl = .init(username: username, passwordGrabber: { _ in try (Array(password().data(using: .utf8)!), []) }, bindingInfo: .unsupported)
295+
self._impl = .init(username: username, passwordGrabber: { _ in try (Array(password().utf8), []) }, bindingInfo: .unsupported)
296296
}
297297

298298
/// Set up a server-side `SCRAM-SHA-256` authentication.
@@ -338,7 +338,7 @@ internal struct SHA256_PLUS: SASLAuthenticationMechanism {
338338
/// - channelBindingData: The appropriate data associated with the RFC5056
339339
/// channel binding specified.
340340
internal init(username: String, password: @escaping () throws -> String, channelBindingName: String, channelBindingData: [UInt8]) {
341-
self._impl = .init(username: username, passwordGrabber: { _ in try (Array(password().data(using: .utf8)!), []) }, bindingInfo: .bind(channelBindingName, channelBindingData))
341+
self._impl = .init(username: username, passwordGrabber: { _ in try (Array(password().utf8), []) }, bindingInfo: .bind(channelBindingName, channelBindingData))
342342
}
343343

344344
/// Set up a server-side `SCRAM-SHA-256` authentication.
@@ -467,7 +467,7 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
467467

468468
// Calculate `AuthMessage`, `ClientSignature`, and `ClientProof`
469469
let saltedPassword = Hi(string: password, salt: serverSalt, iterations: serverIterations)
470-
let clientKey = HMAC<SHA256>.authenticationCode(for: "Client Key".data(using: .utf8)!, using: .init(data: saltedPassword))
470+
let clientKey = HMAC<SHA256>.authenticationCode(for: Data("Client Key".utf8), using: .init(data: saltedPassword))
471471
let storedKey = SHA256.hash(data: Data(clientKey))
472472
var authMessage = firstMessageBare; authMessage.append(.comma); authMessage.append(contentsOf: message); authMessage.append(.comma); authMessage.append(contentsOf: clientFinalNoProof)
473473
let clientSignature = HMAC<SHA256>.authenticationCode(for: authMessage, using: .init(data: storedKey))
@@ -501,7 +501,7 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
501501
switch incomingAttributes.first {
502502
case .v(let verifier):
503503
// Verify server signature
504-
let serverKey = HMAC<SHA256>.authenticationCode(for: "Server Key".data(using: .utf8)!, using: .init(data: saltedPassword))
504+
let serverKey = HMAC<SHA256>.authenticationCode(for: Data("Server Key".utf8), using: .init(data: saltedPassword))
505505
let serverSignature = HMAC<SHA256>.authenticationCode(for: authMessage, using: .init(data: serverKey))
506506

507507
guard Array(serverSignature) == verifier else {
@@ -585,7 +585,7 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
585585
guard nonce == repeatNonce else { throw SASLAuthenticationError.genericAuthenticationFailure }
586586

587587
// Compute client signature
588-
let clientKey = HMAC<SHA256>.authenticationCode(for: "Client Key".data(using: .utf8)!, using: .init(data: saltedPassword))
588+
let clientKey = HMAC<SHA256>.authenticationCode(for: Data("Client Key".utf8), using: .init(data: saltedPassword))
589589
let storedKey = SHA256.hash(data: Data(clientKey))
590590
var authMessage = clientBareFirstMessage; authMessage.append(.comma); authMessage.append(contentsOf: serverFirstMessage); authMessage.append(.comma); authMessage.append(contentsOf: message.dropLast(proof.count + 3))
591591
let clientSignature = HMAC<SHA256>.authenticationCode(for: authMessage, using: .init(data: storedKey))
@@ -604,7 +604,7 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
604604
guard storedKey == restoredKey else { throw SCRAMServerError.invalidProof }
605605

606606
// Compute server signature
607-
let serverKey = HMAC<SHA256>.authenticationCode(for: "Server Key".data(using: .utf8)!, using: .init(data: saltedPassword))
607+
let serverKey = HMAC<SHA256>.authenticationCode(for: Data("Server Key".utf8), using: .init(data: saltedPassword))
608608
let serverSignature = HMAC<SHA256>.authenticationCode(for: authMessage, using: .init(data: serverKey))
609609

610610
// Generate a `server-final-message`
@@ -644,11 +644,16 @@ private func Hi(string: [UInt8], salt: [UInt8], iterations: UInt32) -> [UInt8] {
644644
let key = SymmetricKey(data: string)
645645
var Ui = HMAC<SHA256>.authenticationCode(for: salt + [0x00, 0x00, 0x00, 0x01], using: key) // salt + 0x00000001 as big-endian
646646
var Hi = Array(Ui)
647-
647+
var uiData = [UInt8]()
648+
uiData.reserveCapacity(32)
649+
648650
Hi.withUnsafeMutableBytes { Hibuf -> Void in
649651
for _ in 2...iterations {
650-
Ui = HMAC<SHA256>.authenticationCode(for: Data(Ui), using: key)
651-
652+
uiData.removeAll(keepingCapacity: true)
653+
uiData.append(contentsOf: Ui)
654+
655+
Ui = HMAC<SHA256>.authenticationCode(for: uiData, using: key)
656+
652657
Ui.withUnsafeBytes { Uibuf -> Void in
653658
for i in 0..<Uibuf.count { Hibuf[i] ^= Uibuf[i] }
654659
}

0 commit comments

Comments
 (0)