another.im-ios/AnotherIM/xmpp/utils/Data+Crypto.swift
2024-12-16 08:19:58 +01:00

66 lines
1.7 KiB
Swift

import CommonCrypto
import Foundation
extension Data {
var bytes: [UInt8] {
[UInt8](self)
}
}
extension Array where Element == UInt8 {
var data: Data {
Data(self)
}
}
extension Data {
func hmac(key: Data) -> Data {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), key.bytes, key.count, bytes, count, &digest)
return Data(digest)
}
func sha1() -> Data {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
withUnsafeBytes {
_ = CC_SHA1($0.baseAddress, CC_LONG(self.count), &digest)
}
return digest.data
}
func sha256() -> Data {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
withUnsafeBytes {
_ = CC_SHA256($0.baseAddress, CC_LONG(self.count), &digest)
}
return Data(digest)
}
func pbkdf2(salt: Data, rounds: Int) -> Data {
var buff = [UInt8](repeating: 0, count: salt.count)
(salt as NSData).getBytes(&buff, length: salt.count)
buff.append(contentsOf: [0, 0, 0, 1])
var digest = buff.data.hmac(key: self)
var result = digest
for _ in 1 ..< rounds {
digest = digest.hmac(key: self)
for indx in 0 ..< digest.count {
result[indx] ^= digest[indx]
}
}
return result
}
func xor(other: Data) -> Data {
let otherBytes = other.bytes
var result = bytes
for indx in 0 ..< result.count {
result[indx] ^= otherBytes[indx]
}
return result.data
}
}