11import Crypto
2+ import _CryptoExtras
23import Foundation
34
45extension UInt8 {
@@ -466,8 +467,8 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
466467 // TODO: Perform `Normalize(password)`, aka the SASLprep profile (RFC4013) of stringprep (RFC3454)
467468
468469 // Calculate `AuthMessage`, `ClientSignature`, and `ClientProof`
469- let saltedPassword = Hi ( string: password, salt: serverSalt, iterations: serverIterations)
470- let clientKey = HMAC< SHA256> . authenticationCode( for: Data ( " Client Key " . utf8) , using: . init ( data : saltedPassword) )
470+ let saltedPassword = try Hi ( string: password, salt: serverSalt, iterations: serverIterations)
471+ let clientKey = HMAC< SHA256> . authenticationCode( for: Data ( " Client Key " . utf8) , using: saltedPassword)
471472 let storedKey = SHA256 . hash ( data: Data ( clientKey) )
472473 var authMessage = firstMessageBare; authMessage. append ( . comma) ; authMessage. append ( contentsOf: message) ; authMessage. append ( . comma) ; authMessage. append ( contentsOf: clientFinalNoProof)
473474 let clientSignature = HMAC< SHA256> . authenticationCode( for: authMessage, using: . init( data: storedKey) )
@@ -485,9 +486,11 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
485486 var clientFinalMessage = clientFinalNoProof; clientFinalMessage. append ( . comma)
486487 guard let proofPart = SCRAMMessageParser . serialize ( [ . p( Array ( clientProof) ) ] ) else { throw SASLAuthenticationError . genericAuthenticationFailure }
487488 clientFinalMessage. append ( contentsOf: proofPart)
488-
489+
490+ let saltedPasswordBytes = saltedPassword. withUnsafeBytes { [ UInt8] ( $0) }
491+
489492 // Save state and send
490- self . state = . clientSentFinalMessage( saltedPassword: saltedPassword , authMessage: authMessage)
493+ self . state = . clientSentFinalMessage( saltedPassword: saltedPasswordBytes , authMessage: authMessage)
491494 return . continue( response: clientFinalMessage)
492495 }
493496
@@ -640,24 +643,12 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
640643 HMAC() == output length of H().
641644 ````
642645*/
643- private func Hi( string: [ UInt8 ] , salt: [ UInt8 ] , iterations: UInt32 ) -> [ UInt8 ] {
644- let key = SymmetricKey ( data: string)
645- var Ui = HMAC< SHA256> . authenticationCode( for: salt + [ 0x00 , 0x00 , 0x00 , 0x01 ] , using: key) // salt + 0x00000001 as big-endian
646- var Hi = Array ( Ui)
647- var uiData = [ UInt8] ( )
648- uiData. reserveCapacity ( 32 )
649-
650- Hi . withUnsafeMutableBytes { Hibuf -> Void in
651- for _ in 2 ... iterations {
652- uiData. removeAll ( keepingCapacity: true )
653- uiData. append ( contentsOf: Ui)
654-
655- Ui = HMAC< SHA256> . authenticationCode( for: uiData, using: key)
656-
657- Ui . withUnsafeBytes { Uibuf -> Void in
658- for i in 0 ..< Uibuf . count { Hibuf [ i] ^= Uibuf [ i] }
659- }
660- }
661- }
662- return Hi
646+ private func Hi( string: [ UInt8 ] , salt: [ UInt8 ] , iterations: UInt32 ) throws -> SymmetricKey {
647+ try KDF . Insecure. PBKDF2. deriveKey (
648+ from: string,
649+ salt: salt,
650+ using: . sha256,
651+ outputByteCount: 32 ,
652+ unsafeUncheckedRounds: Int ( iterations)
653+ )
663654}
0 commit comments