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 data.isEmpty { return data } let blockSize = 16 let totalBlocks = data.count / blockSize guard totalBlocks > 0 else { return data } var cryptBlocks = cryptByteBlock var skipBlocks = skipByteBlock // ISO/Chromium: 0:0 → alles encrypted als één CBC-run. if cryptBlocks == 0 && skipBlocks == 0 { cryptBlocks = totalBlocks skipBlocks = 0 } if cryptBlocks <= 0 { return data } var out = data var blockIv = Data(count: 16) let ivn = min(iv.count, 16) blockIv.replaceSubrange(0..= blockSize { 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 } }