Browse Source

Split FinalizingModeWorker into FinalizingEncryptModeWorker and FinalizingDecryptModeWorker

Marcin Krzyzanowski 7 years ago
parent
commit
33bf336d64

+ 2 - 2
Sources/CryptoSwift/BlockDecryptor.swift

@@ -47,7 +47,7 @@ public class BlockDecryptor: Cryptor, Updatable {
         for var chunk in accumulatedWithoutSuffix.batched(by: blockSize) {
         for var chunk in accumulatedWithoutSuffix.batched(by: blockSize) {
             if isLast || (accumulatedWithoutSuffix.count - processedBytesCount) >= blockSize {
             if isLast || (accumulatedWithoutSuffix.count - processedBytesCount) >= blockSize {
 
 
-                if isLast, var finalizingWorker = worker as? FinalizingModeWorker {
+                if isLast, var finalizingWorker = worker as? FinalizingDecryptModeWorker {
                     chunk = try finalizingWorker.willDecryptLast(bytes: chunk + accumulated.suffix(worker.additionalBufferSize)) // tag size
                     chunk = try finalizingWorker.willDecryptLast(bytes: chunk + accumulated.suffix(worker.additionalBufferSize)) // tag size
                 }
                 }
 
 
@@ -55,7 +55,7 @@ public class BlockDecryptor: Cryptor, Updatable {
                     plaintext += worker.decrypt(block: chunk)
                     plaintext += worker.decrypt(block: chunk)
                 }
                 }
 
 
-                if var finalizingWorker = worker as? FinalizingModeWorker, isLast == true {
+                if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true {
                     plaintext = try finalizingWorker.didDecryptLast(block: plaintext.slice)
                     plaintext = try finalizingWorker.didDecryptLast(block: plaintext.slice)
                 }
                 }
 
 

+ 1 - 1
Sources/CryptoSwift/BlockEncryptor.swift

@@ -44,7 +44,7 @@ final class BlockEncryptor: Cryptor, Updatable {
         // Stream encrypts all, so it removes all elements
         // Stream encrypts all, so it removes all elements
         accumulated.removeFirst(encrypted.count)
         accumulated.removeFirst(encrypted.count)
 
 
-        if var finalizingWorker = worker as? FinalizingModeWorker, isLast == true {
+        if var finalizingWorker = worker as? FinalizingEncryptModeWorker, isLast == true {
             encrypted = try finalizingWorker.finalize(encrypt: encrypted.slice)
             encrypted = try finalizingWorker.finalize(encrypt: encrypted.slice)
         }
         }
 
 

+ 5 - 1
Sources/CryptoSwift/BlockMode/CCM.swift

@@ -52,7 +52,7 @@ public struct CCM: StreamMode {
     }
     }
 }
 }
 
 
-class CCMModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker, FinalizingModeWorker {
+class CCMModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker {
     typealias Counter = Int
     typealias Counter = Int
     var counter = 0
     var counter = 0
 
 
@@ -162,6 +162,10 @@ class CCMModeWorker: StreamModeWorker, SeekableModeWorker, CounterModeWorker, Fi
         return Array(ciphertext) + (xor(tag, S0) as Array<UInt8>)
         return Array(ciphertext) + (xor(tag, S0) as Array<UInt8>)
     }
     }
 
 
+    func finalize(decrypt ciphertext: ArraySlice<UInt8>) throws -> Array<UInt8> {
+        return []
+    }
+
     func willDecryptLast(bytes ciphertext: ArraySlice<UInt8>) throws -> ArraySlice<UInt8> {
     func willDecryptLast(bytes ciphertext: ArraySlice<UInt8>) throws -> ArraySlice<UInt8> {
         return ciphertext
         return ciphertext
     }
     }

+ 7 - 1
Sources/CryptoSwift/BlockMode/CipherModeWorker.swift

@@ -42,10 +42,16 @@ public protocol SeekableModeWorker: CipherModeWorker {
 public protocol StreamModeWorker: CipherModeWorker {
 public protocol StreamModeWorker: CipherModeWorker {
 }
 }
 
 
-public protocol FinalizingModeWorker: CipherModeWorker {
+public protocol FinalizingEncryptModeWorker: CipherModeWorker {
     // Any final calculations, eg. calculate tag
     // Any final calculations, eg. calculate tag
     // Called after the last block is encrypted
     // Called after the last block is encrypted
     mutating func finalize(encrypt ciphertext: ArraySlice<UInt8>) throws -> Array<UInt8>
     mutating func finalize(encrypt ciphertext: ArraySlice<UInt8>) throws -> Array<UInt8>
+}
+
+public protocol FinalizingDecryptModeWorker: CipherModeWorker {
+    // Any final calculations, eg. calculate tag
+    // Called after the last block is encrypted
+    mutating func finalize(decrypt plaintext: ArraySlice<UInt8>) throws -> Array<UInt8>
     // Called before decryption, hence input is ciphertext.
     // Called before decryption, hence input is ciphertext.
     // ciphertext is either a last block, or a tag (for stream workers)
     // ciphertext is either a last block, or a tag (for stream workers)
     mutating func willDecryptLast(bytes ciphertext: ArraySlice<UInt8>) throws -> ArraySlice<UInt8>
     mutating func willDecryptLast(bytes ciphertext: ArraySlice<UInt8>) throws -> ArraySlice<UInt8>

+ 5 - 1
Sources/CryptoSwift/BlockMode/GCM.swift

@@ -81,7 +81,7 @@ public final class GCM: BlockMode {
 
 
 // MARK: - Worker
 // MARK: - Worker
 
 
-final class GCMModeWorker: BlockModeWorker, FinalizingModeWorker {
+final class GCMModeWorker: BlockModeWorker, FinalizingEncryptModeWorker, FinalizingDecryptModeWorker {
     let cipherOperation: CipherOperationOnBlock
     let cipherOperation: CipherOperationOnBlock
 
 
     // Callback called when authenticationTag is ready
     // Callback called when authenticationTag is ready
@@ -183,6 +183,10 @@ final class GCMModeWorker: BlockModeWorker, FinalizingModeWorker {
         }
         }
     }
     }
 
 
+    func finalize(decrypt plaintext: ArraySlice<UInt8>) throws -> Array<UInt8> {
+        return Array(plaintext)
+    }
+
     // The authenticated decryption operation has five inputs: K, IV , C, A, and T. It has only a single
     // The authenticated decryption operation has five inputs: K, IV , C, A, and T. It has only a single
     // output, either the plaintext value P or a special symbol FAIL that indicates that the inputs are not
     // output, either the plaintext value P or a special symbol FAIL that indicates that the inputs are not
     // authentic.
     // authentic.

+ 3 - 5
Sources/CryptoSwift/StreamDecryptor.swift

@@ -27,10 +27,8 @@ final class StreamDecryptor: Cryptor, Updatable {
 
 
     // MARK: Updatable
     // MARK: Updatable
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool) throws -> Array<UInt8> {
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool) throws -> Array<UInt8> {
-        let accumulated = Array(bytes)
-
         var plaintext = Array<UInt8>(reserveCapacity: bytes.count)
         var plaintext = Array<UInt8>(reserveCapacity: bytes.count)
-        for chunk in accumulated.batched(by: blockSize) {
+        for chunk in Array(bytes).batched(by: blockSize) {
             plaintext += worker.encrypt(block: chunk)
             plaintext += worker.encrypt(block: chunk)
         }
         }
 
 
@@ -44,8 +42,8 @@ final class StreamDecryptor: Cryptor, Updatable {
             plaintext = padding.remove(from: plaintext, blockSize: blockSize - lastBlockRemainder)
             plaintext = padding.remove(from: plaintext, blockSize: blockSize - lastBlockRemainder)
         }
         }
 
 
-        if var finalizingWorker = worker as? FinalizingModeWorker, isLast == true {
-            plaintext = try finalizingWorker.finalize(encrypt: plaintext.slice)
+        if var finalizingWorker = worker as? FinalizingDecryptModeWorker, isLast == true {
+            plaintext = try finalizingWorker.finalize(decrypt: plaintext.slice)
         }
         }
 
 
         return plaintext
         return plaintext

+ 2 - 4
Sources/CryptoSwift/StreamEncryptor.swift

@@ -16,8 +16,6 @@ final class StreamEncryptor: Cryptor, Updatable {
     private let blockSize: Int
     private let blockSize: Int
     private var worker: CipherModeWorker
     private var worker: CipherModeWorker
     private let padding: Padding
     private let padding: Padding
-    // Accumulated bytes. Not all processed bytes.
-    private var accumulated = Array<UInt8>(reserveCapacity: 16)
 
 
     private var lastBlockRemainder = 0
     private var lastBlockRemainder = 0
 
 
@@ -29,7 +27,7 @@ final class StreamEncryptor: Cryptor, Updatable {
 
 
     // MARK: Updatable
     // MARK: Updatable
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool) throws -> Array<UInt8> {
     public func update(withBytes bytes: ArraySlice<UInt8>, isLast: Bool) throws -> Array<UInt8> {
-        accumulated = Array(bytes)
+        var accumulated = Array(bytes)
         if isLast {
         if isLast {
             // CTR doesn't need padding. Really. Add padding to the last block if really want. but... don't.
             // CTR doesn't need padding. Really. Add padding to the last block if really want. but... don't.
             accumulated = padding.add(to: accumulated, blockSize: blockSize - lastBlockRemainder)
             accumulated = padding.add(to: accumulated, blockSize: blockSize - lastBlockRemainder)
@@ -45,7 +43,7 @@ final class StreamEncryptor: Cryptor, Updatable {
             lastBlockRemainder = encrypted.count.quotientAndRemainder(dividingBy: blockSize).remainder
             lastBlockRemainder = encrypted.count.quotientAndRemainder(dividingBy: blockSize).remainder
         }
         }
 
 
-        if var finalizingWorker = worker as? FinalizingModeWorker, isLast == true {
+        if var finalizingWorker = worker as? FinalizingEncryptModeWorker, isLast == true {
             encrypted = try finalizingWorker.finalize(encrypt: encrypted.slice)
             encrypted = try finalizingWorker.finalize(encrypt: encrypted.slice)
         }
         }