1
1
import Crypto
2
+ import _CryptoExtras
2
3
import Foundation
3
4
4
5
extension UInt8 {
@@ -466,8 +467,8 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
466
467
// TODO: Perform `Normalize(password)`, aka the SASLprep profile (RFC4013) of stringprep (RFC3454)
467
468
468
469
// 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)
471
472
let storedKey = SHA256 . hash ( data: Data ( clientKey) )
472
473
var authMessage = firstMessageBare; authMessage. append ( . comma) ; authMessage. append ( contentsOf: message) ; authMessage. append ( . comma) ; authMessage. append ( contentsOf: clientFinalNoProof)
473
474
let clientSignature = HMAC< SHA256> . authenticationCode( for: authMessage, using: . init( data: storedKey) )
@@ -485,9 +486,11 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
485
486
var clientFinalMessage = clientFinalNoProof; clientFinalMessage. append ( . comma)
486
487
guard let proofPart = SCRAMMessageParser . serialize ( [ . p( Array ( clientProof) ) ] ) else { throw SASLAuthenticationError . genericAuthenticationFailure }
487
488
clientFinalMessage. append ( contentsOf: proofPart)
488
-
489
+
490
+ let saltedPasswordBytes = saltedPassword. withUnsafeBytes { [ UInt8] ( $0) }
491
+
489
492
// Save state and send
490
- self . state = . clientSentFinalMessage( saltedPassword: saltedPassword , authMessage: authMessage)
493
+ self . state = . clientSentFinalMessage( saltedPassword: saltedPasswordBytes , authMessage: authMessage)
491
494
return . continue( response: clientFinalMessage)
492
495
}
493
496
@@ -640,24 +643,12 @@ fileprivate final class SASLMechanism_SCRAM_SHA256_Common {
640
643
HMAC() == output length of H().
641
644
````
642
645
*/
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
+ )
663
654
}
0 commit comments