import CommonCrypto import Foundation enum AesCtr { /// AES-128-CTR (big-endian counter), zoals CENC `cenc` scheme. static func crypt(key: Data, iv: Data, data: Data) -> Data? { guard key.count == 16, data.count > 0 else { return data.isEmpty ? data : nil } var counter = Data(count: 16) let copyLen = min(iv.count, 16) counter.replaceSubrange(0.. Data? { guard key.count == 16 else { return nil } if cryptByteBlock <= 0 { return data } let cryptLen = 16 * cryptByteBlock let skipLen = 16 * max(skipByteBlock, 0) var result = data var offset = 0 var blockIv = Data(count: 16) let ivCopy = min(iv.count, 16) blockIv.replaceSubrange(0.. Data? { guard data.count % 16 == 0, data.count > 0 else { return data.isEmpty ? data : nil } var out = Data(count: data.count) var moved = 0 var ivMut = iv if ivMut.count < 16 { ivMut.append(Data(count: 16 - ivMut.count)) } let status = out.withUnsafeMutableBytes { outBytes in data.withUnsafeBytes { inBytes in key.withUnsafeBytes { keyBytes in ivMut.withUnsafeMutableBytes { ivBytes in CCCrypt( CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(0), keyBytes.baseAddress, key.count, ivBytes.baseAddress, inBytes.baseAddress, data.count, outBytes.baseAddress, data.count, &moved ) } } } } guard status == kCCSuccess, moved == data.count else { return nil } return out } }