2024-09-03 15:13:58 +00:00
|
|
|
import CryptoKit
|
|
|
|
import Foundation
|
|
|
|
import MartinOMEMO
|
|
|
|
|
|
|
|
final class AESGSMEngine: AES_GCM_Engine {
|
|
|
|
static let shared = AESGSMEngine()
|
|
|
|
|
|
|
|
private init() {}
|
|
|
|
|
|
|
|
func encrypt(iv: Data, key: Data, message: Data, output: UnsafeMutablePointer<Data>?, tag: UnsafeMutablePointer<Data>?) -> Bool {
|
|
|
|
do {
|
|
|
|
let symmetricKey = SymmetricKey(data: key)
|
|
|
|
let sealedBox = try AES.GCM.seal(message, using: symmetricKey, nonce: AES.GCM.Nonce(data: iv))
|
|
|
|
|
2024-09-08 17:28:17 +00:00
|
|
|
if let output = output {
|
|
|
|
output.pointee = sealedBox.ciphertext
|
2024-09-03 15:13:58 +00:00
|
|
|
}
|
|
|
|
if let tag = tag {
|
|
|
|
tag.pointee = sealedBox.tag
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
} catch {
|
|
|
|
print("Encryption error: \(error)")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func decrypt(iv: Data, key: Data, encoded: Data, auth tag: Data?, output: UnsafeMutablePointer<Data>?) -> Bool {
|
|
|
|
do {
|
|
|
|
let symmetricKey = SymmetricKey(data: key)
|
2024-09-08 16:16:01 +00:00
|
|
|
|
|
|
|
let sealedBox: AES.GCM.SealedBox
|
|
|
|
if let tag {
|
|
|
|
sealedBox = try AES.GCM.SealedBox(nonce: AES.GCM.Nonce(data: iv), ciphertext: encoded, tag: tag)
|
|
|
|
} else {
|
|
|
|
let embeddedTag = encoded.subdata(in: (encoded.count - 16) ..< encoded.count)
|
|
|
|
let payload = encoded.subdata(in: 0 ..< (encoded.count - 16))
|
|
|
|
sealedBox = try AES.GCM.SealedBox(nonce: AES.GCM.Nonce(data: iv), ciphertext: payload, tag: embeddedTag)
|
2024-09-03 15:13:58 +00:00
|
|
|
}
|
|
|
|
|
2024-09-08 16:16:01 +00:00
|
|
|
let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey)
|
2024-09-03 15:13:58 +00:00
|
|
|
if let output = output {
|
|
|
|
output.pointee = decryptedData
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
} catch {
|
|
|
|
print("Decryption error: \(error)")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
2024-09-08 14:57:50 +00:00
|
|
|
|
|
|
|
static func generateIV() throws -> Data {
|
|
|
|
var bytes = [Int8](repeating: 0, count: 12)
|
|
|
|
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
|
|
|
|
if status != errSecSuccess {
|
|
|
|
throw AppError.securityError
|
|
|
|
}
|
|
|
|
return Data(bytes: bytes, count: bytes.count)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func generateKey() throws -> Data {
|
|
|
|
let key = SymmetricKey(size: .bits256)
|
|
|
|
return key.withUnsafeBytes { Data($0) }
|
|
|
|
}
|
2024-09-03 15:13:58 +00:00
|
|
|
}
|