TM-SGNL-iOS/SignalServiceKit/Util/StreamTransform/Input/DecryptingStreamTransform.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

56 lines
1.7 KiB
Swift

//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public class DecryptingStreamTransform: StreamTransform, FinalizableStreamTransform {
public enum Error: Swift.Error {
case initialBufferTooSmall
case notInitialized
}
public enum Constants {
static let HeaderSize = 16
}
private let encryptionKey: Data
private var cipherContext: CipherContext?
private var finalized = false
public var hasFinalized: Bool { finalized }
public var hasInitialized = false
init(encryptionKey: Data) throws {
self.encryptionKey = encryptionKey
}
public func transform(data: Data) throws -> Data {
var inputBuffer = data
if !hasInitialized {
guard inputBuffer.count > Constants.HeaderSize else { throw Error.initialBufferTooSmall }
// read the IV
let iv = data.subdata(in: 0..<Constants.HeaderSize)
inputBuffer = inputBuffer.subdata(in: Constants.HeaderSize..<inputBuffer.count)
self.cipherContext = try CipherContext(
operation: .decrypt,
algorithm: .aes,
options: .pkcs7Padding,
key: encryptionKey,
iv: iv
)
hasInitialized = true
}
guard let cipherContext else { throw Error.notInitialized }
return try cipherContext.update(inputBuffer)
}
public func finalize() throws -> Data {
guard let cipherContext else { throw Error.notInitialized }
guard !finalized else { return Data() }
finalized = true
return try cipherContext.finalize()
}
}