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?, tag: UnsafeMutablePointer?) -> Bool { do { let symmetricKey = SymmetricKey(data: key) let sealedBox = try AES.GCM.seal(message, using: symmetricKey, nonce: AES.GCM.Nonce(data: iv)) if let output = output, let data = sealedBox.combined { output.pointee = data } 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?) -> Bool { do { let symmetricKey = SymmetricKey(data: key) 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) } let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey) if let output = output { output.pointee = decryptedData } return true } catch { print("Decryption error: \(error)") return false } } 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) } } }