|
|
|
|
@@ -319,6 +319,31 @@ class NearbyConnection{
|
|
|
|
|
return String(format: "%04d", abs(hash))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static func hkdfExtract(salt:Data, ikm:Data) -> Data{
|
|
|
|
|
return HMAC<SHA256>.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static func hkdfExpand(prk:Data, info:Data, length:Int) -> Data{
|
|
|
|
|
var okm=Data()
|
|
|
|
|
var t=Data()
|
|
|
|
|
var i=0
|
|
|
|
|
while okm.count<length{
|
|
|
|
|
i=i+1
|
|
|
|
|
let toDigest=t+info+Data([UInt8(truncatingIfNeeded: i)])
|
|
|
|
|
t=HMAC<SHA256>.authenticationCode(for: toDigest, using: SymmetricKey(data: prk)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
|
|
|
|
|
okm=okm+t
|
|
|
|
|
}
|
|
|
|
|
return okm.subdata(in: 0..<length)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static func hkdf(inputKeyMaterial:SymmetricKey, salt:Data, info:Data, outputByteCount:Int) -> SymmetricKey{
|
|
|
|
|
if #available(macOS 11.0, *){
|
|
|
|
|
return HKDF<SHA256>.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount)
|
|
|
|
|
}else{
|
|
|
|
|
return SymmetricKey(data: hkdfExpand(prk: hkdfExtract(salt: salt, ikm: inputKeyMaterial.withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})), info: info, length: outputByteCount))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{
|
|
|
|
|
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }
|
|
|
|
|
|
|
|
|
|
@@ -341,8 +366,8 @@ class NearbyConnection{
|
|
|
|
|
var ukeyInfo=Data()
|
|
|
|
|
ukeyInfo.append(ukeyClientInitMsgData!)
|
|
|
|
|
ukeyInfo.append(ukeyServerInitMsgData!)
|
|
|
|
|
let authString=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
|
|
|
|
let nextSecret=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
|
|
|
|
let authString=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
|
|
|
|
let nextSecret=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
|
|
|
|
|
|
|
|
|
pinCode=NearbyConnection.pinCodeFromAuthKey(authString)
|
|
|
|
|
|
|
|
|
|
@@ -350,17 +375,17 @@ class NearbyConnection{
|
|
|
|
|
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
|
|
|
|
|
0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10])
|
|
|
|
|
|
|
|
|
|
let d2dClientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
let d2dServerKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
let d2dClientKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
let d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
|
|
|
|
|
sha=SHA256()
|
|
|
|
|
sha.update(data: "SecureMessage".data(using: .utf8)!)
|
|
|
|
|
let smsgSalt=Data(sha.finalize())
|
|
|
|
|
|
|
|
|
|
let clientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
|
|
|
|
let clientHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
let serverKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
|
|
|
|
let serverHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
let clientKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
|
|
|
|
let clientHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
let serverKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
|
|
|
|
let serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
|
|
|
|
|
|
|
|
|
if isServer(){
|
|
|
|
|
decryptKey=clientKey
|
|
|
|
|
|