Prechádzať zdrojové kódy

Remove Cipher enum. Implement Cipher protocol.

Marcin Krzyżanowski 10 rokov pred
rodič
commit
774d567b0f

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2 - 0
CryptoSwift/AES.swift


+ 3 - 3
CryptoSwift/CSArrayType+Extensions.swift

@@ -55,11 +55,11 @@ public extension CSArrayType where Generator.Element == UInt8 {
     }
     }
     
     
     public func encrypt(cipher: Cipher) throws -> [Generator.Element] {
     public func encrypt(cipher: Cipher) throws -> [Generator.Element] {
-        return try cipher.encrypt(cs_arrayValue())
+        return try cipher.cipherEncrypt(cs_arrayValue())
     }
     }
-    
+
     public func decrypt(cipher: Cipher) throws -> [Generator.Element] {
     public func decrypt(cipher: Cipher) throws -> [Generator.Element] {
-        return try cipher.decrypt(cs_arrayValue())
+        return try cipher.cipherDecrypt(cs_arrayValue())
     }
     }
     
     
     public func authenticate(authenticator: Authenticator) throws -> [Generator.Element] {
     public func authenticate(authenticator: Authenticator) throws -> [Generator.Element] {

+ 12 - 0
CryptoSwift/ChaCha20.swift

@@ -179,6 +179,18 @@ final public class ChaCha20 {
     }
     }
 }
 }
 
 
+// MARK: - Cipher
+
+extension ChaCha20: Cipher {
+    public func cipherEncrypt(bytes:[UInt8]) throws -> [UInt8] {
+        return try self.encrypt(bytes)
+    }
+    
+    public func cipherDecrypt(bytes: [UInt8]) throws -> [UInt8] {
+        return try self.decrypt(bytes)
+    }
+}
+
 // MARK: Helpers
 // MARK: Helpers
 
 
 /// Change array to number. It's here because arrayOfBytes is too slow
 /// Change array to number. It's here because arrayOfBytes is too slow

+ 11 - 69
CryptoSwift/Cipher.swift

@@ -8,77 +8,19 @@
 
 
 import Darwin
 import Darwin
 
 
-public enum Cipher {
-    
-    public enum Error: ErrorType {
-        case EncryptError
-        case DecryptError
-    }
-    
-    /**
-    ChaCha20
-    
-    - parameter key: Encryption key
-    - parameter iv:  Initialization Vector
-    
-    - returns: Value of Cipher
-    */
-    case ChaCha20(key: [UInt8], iv: [UInt8])
-    /**
-    AES
-    
-    - parameter key:       Encryption key
-    - parameter iv:        Initialization Vector
-    - parameter blockMode: Block mode (CBC by default)
-    
-    - returns: Value of Cipher
-    */
-    case AES(key: [UInt8], iv: [UInt8], blockMode: CipherBlockMode)
-    
-    /**
-    Encrypt message
-    
-    - parameter message: Plaintext message
-    
-    - returns: encrypted message
-    */
-    public func encrypt(bytes: [UInt8]) throws -> [UInt8] {
-        switch (self) {
-            case .ChaCha20(let key, let iv):
-                guard let chacha = CryptoSwift.ChaCha20(key: key, iv: iv) else {
-                    throw Error.EncryptError
-                }
-                return try chacha.encrypt(bytes)
-            case .AES(let key, let iv, let blockMode):
-                guard let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode) else {
-                    throw Error.EncryptError
-                }
-                return try aes.encrypt(bytes)
-        }
-    }
-    
-    /**
-    Decrypt message
-    
-    - parameter message: Message data
+public enum CipherError: ErrorType {
+    case Encrypt
+    case Decrypt
+}
+
+public protocol Cipher {
+    func cipherEncrypt(bytes: [UInt8]) throws -> [UInt8]
+    func cipherDecrypt(bytes: [UInt8]) throws -> [UInt8]
     
     
-    - returns: Plaintext message
-    */
-    public func decrypt(bytes: [UInt8]) throws -> [UInt8] {
-        switch (self) {
-            case .ChaCha20(let key, let iv):
-                guard let chacha = CryptoSwift.ChaCha20(key: key, iv: iv) else {
-                    throw Error.DecryptError
-                }
-                return try chacha.decrypt(bytes)
-            case .AES(let key, let iv, let blockMode):
-                guard let aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode) else {
-                    throw Error.DecryptError
-                }
-                return try aes.decrypt(bytes)
-        }
-    }
+    static func randomIV(blockSize:Int) -> [UInt8]
+}
 
 
+extension Cipher {
     static public func randomIV(blockSize:Int) -> [UInt8] {
     static public func randomIV(blockSize:Int) -> [UInt8] {
         var randomIV:[UInt8] = [UInt8]();
         var randomIV:[UInt8] = [UInt8]();
         for (var i = 0; i < blockSize; i++) {
         for (var i = 0; i < blockSize; i++) {

+ 3 - 3
CryptoSwift/Foundation/AES+Foundation.swift

@@ -9,11 +9,11 @@
 import Foundation
 import Foundation
 
 
 extension AES {
 extension AES {
-    convenience public init?(key:String, iv:String, blockMode:CipherBlockMode = .CBC) {
+    convenience public init(key:String, iv:String, blockMode:CipherBlockMode = .CBC) throws {
         guard let kkey = key.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes(), let iiv = iv.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes() else {
         guard let kkey = key.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes(), let iiv = iv.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)?.arrayOfBytes() else {
-            return nil
+            throw Error.InvalidKeyOrInitializationVector
         }
         }
         
         
-        self.init(key: kkey, iv: iiv, blockMode: blockMode)
+        try self.init(key: kkey, iv: iiv, blockMode: blockMode)
     }
     }
 }
 }

+ 2 - 2
CryptoSwift/Foundation/NSData+Extension.swift

@@ -71,12 +71,12 @@ extension NSData {
     }
     }
 
 
     public func encrypt(cipher: Cipher) throws -> NSData {
     public func encrypt(cipher: Cipher) throws -> NSData {
-        let encrypted = try cipher.encrypt(self.arrayOfBytes())
+        let encrypted = try cipher.cipherEncrypt(self.arrayOfBytes())
         return NSData.withBytes(encrypted)
         return NSData.withBytes(encrypted)
     }
     }
 
 
     public func decrypt(cipher: Cipher) throws -> NSData {
     public func decrypt(cipher: Cipher) throws -> NSData {
-        let decrypted = try cipher.decrypt(self.arrayOfBytes())
+        let decrypted = try cipher.cipherDecrypt(self.arrayOfBytes())
         return NSData.withBytes(decrypted)
         return NSData.withBytes(decrypted)
     }
     }
     
     

+ 64 - 55
CryptoSwiftTests/AESTests.swift

@@ -19,14 +19,38 @@ final class AESTests: XCTestCase {
         
         
         let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
         let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
         
         
-        if let aes = AES(key: key, iv: iv, blockMode: .CBC) {
-            let encrypted = try! aes.encrypt(input, padding: nil)
-            XCTAssertEqual(encrypted, expected, "encryption failed")
-            let decrypted = try! aes.decrypt(encrypted, padding: nil)
-            XCTAssertEqual(decrypted, input, "decryption failed")
-        } else {
-            XCTAssert(false, "failed")
-        }
+        let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
+        let encrypted = try! aes.encrypt(input, padding: nil)
+        XCTAssertEqual(encrypted, expected, "encryption failed")
+        let decrypted = try! aes.decrypt(encrypted, padding: nil)
+        XCTAssertEqual(decrypted, input, "decryption failed")
+    }
+    
+    func testFoo() {
+        let input = [0,1,2,3,4,5,6,7,8,9] as [UInt8]
+        input.encrypt(AES(key: "secret0key000000", iv:"0123456789012345", blockMode: .CBC))
+        AES(key: "secret0key000000", iv:"0123456789012345", blockMode: .CBC)
+        let encrypted = Cipher.AES(key: key, iv: iv, blockMode: .CBC).encrypt(input)
+//        let input = NSData()
+//        let encrypted = try! AES(key: "secret0key000000", iv:"0123456789012345").encrypt(input.arrayOfBytes())
+//        let input = NSData()
+//        let encrypted = try! input.encrypt(AES(key: "secret0key000000", iv:"0123456789012345"))
+//        let encrypted = try! AES(key: "secret0key000000", iv:"0123456789012345").encrypt(input.arrayOfBytes())
+        
+//let input = [0,1,2,3,4,5,6,7,8,9] as [UInt8]
+//
+//let key = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] as [UInt8]
+//let iv = AES.randomIV(AES.blockSize)
+//
+//do {
+//    let encrypted = try AES(key: key, iv: iv, blockMode: .CBC).encrypt(input, padding: PKCS7())
+//    let decrypted = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(input, padding: PKCS7())
+//} catch AES.Error.BlockSizeExceeded {
+//    // block size exceeded
+//} catch {
+//    // some error
+//}
+
     }
     }
 
 
     func testAES_encrypt3() {
     func testAES_encrypt3() {
@@ -36,14 +60,11 @@ final class AESTests: XCTestCase {
         
         
         let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
         let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
         
         
-        if let aes = AES(key: key, iv: iv, blockMode: .CBC) {
-            let encrypted = try! aes.encrypt(input, padding: nil)
-            XCTAssertEqual(encrypted, expected, "encryption failed")
-            let decrypted = try! aes.decrypt(encrypted, padding: nil)
-            XCTAssertEqual(decrypted, input, "decryption failed")
-        } else {
-            XCTAssert(false, "failed")
-        }
+        let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
+        let encrypted = try! aes.encrypt(input, padding: nil)
+        XCTAssertEqual(encrypted, expected, "encryption failed")
+        let decrypted = try! aes.decrypt(encrypted, padding: nil)
+        XCTAssertEqual(decrypted, input, "decryption failed")
     }
     }
     
     
     func testAES_encrypt() {
     func testAES_encrypt() {
@@ -57,14 +78,11 @@ final class AESTests: XCTestCase {
             0xd8, 0xcd, 0xb7, 0x80,
             0xd8, 0xcd, 0xb7, 0x80,
             0x70, 0xb4, 0xc5, 0x5a];
             0x70, 0xb4, 0xc5, 0x5a];
         
         
-        if let aes = AES(key: aesKey, blockMode: .ECB) {
-            let encrypted = try! aes.encrypt(input, padding: nil)
-            XCTAssertEqual(encrypted, expected, "encryption failed")
-            let decrypted = try! aes.decrypt(encrypted, padding: nil)
-            XCTAssertEqual(decrypted, input, "decryption failed")
-        } else {
-            XCTAssert(false, "failed")
-        }
+        let aes = try! AES(key: aesKey, blockMode: .ECB)
+        let encrypted = try! aes.encrypt(input, padding: nil)
+        XCTAssertEqual(encrypted, expected, "encryption failed")
+        let decrypted = try! aes.decrypt(encrypted, padding: nil)
+        XCTAssertEqual(decrypted, input, "decryption failed")
     }
     }
 
 
     func testAES_encrypt_cbc() {
     func testAES_encrypt_cbc() {
@@ -73,15 +91,12 @@ final class AESTests: XCTestCase {
         let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
         let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
         let expected:[UInt8] = [0x76,0x49,0xab,0xac,0x81,0x19,0xb2,0x46,0xce,0xe9,0x8e,0x9b,0x12,0xe9,0x19,0x7d];
         let expected:[UInt8] = [0x76,0x49,0xab,0xac,0x81,0x19,0xb2,0x46,0xce,0xe9,0x8e,0x9b,0x12,0xe9,0x19,0x7d];
         
         
-        if let aes = AES(key: key, iv:iv, blockMode: .CBC) {
-            XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
-            let encrypted = try! aes.encrypt(plaintext, padding: nil)
-            XCTAssertEqual(encrypted, expected, "encryption failed")
-            let decrypted = try! aes.decrypt(encrypted, padding: nil)
-            XCTAssertEqual(decrypted, plaintext, "decryption failed")
-        } else {
-            XCTAssert(false, "failed")
-        }
+        let aes = try! AES(key: key, iv:iv, blockMode: .CBC)
+        XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
+        let encrypted = try! aes.encrypt(plaintext, padding: nil)
+        XCTAssertEqual(encrypted, expected, "encryption failed")
+        let decrypted = try! aes.decrypt(encrypted, padding: nil)
+        XCTAssertEqual(decrypted, plaintext, "decryption failed")
     }
     }
     
     
     func testAES_encrypt_cfb() {
     func testAES_encrypt_cfb() {
@@ -90,15 +105,12 @@ final class AESTests: XCTestCase {
         let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
         let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
         let expected:[UInt8] = [0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20,0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a];
         let expected:[UInt8] = [0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20,0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a];
         
         
-        if let aes = AES(key: key, iv:iv, blockMode: .CFB) {
-            XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
-            let encrypted = try! aes.encrypt(plaintext, padding: nil)
-            XCTAssertEqual(encrypted, expected, "encryption failed")
-            let decrypted = try! aes.decrypt(encrypted, padding: nil)
-            XCTAssertEqual(decrypted, plaintext, "decryption failed")
-        } else {
-            XCTAssert(false, "failed")
-        }
+        let aes = try! AES(key: key, iv:iv, blockMode: .CFB)
+        XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
+        let encrypted = try! aes.encrypt(plaintext, padding: nil)
+        XCTAssertEqual(encrypted, expected, "encryption failed")
+        let decrypted = try! aes.decrypt(encrypted, padding: nil)
+        XCTAssertEqual(decrypted, plaintext, "decryption failed")
     }
     }
     
     
     func testAES_encrypt_ctr() {
     func testAES_encrypt_ctr() {
@@ -107,24 +119,21 @@ final class AESTests: XCTestCase {
         let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
         let plaintext:[UInt8] = [0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a]
         let expected:[UInt8] = [103, 238, 5, 84, 116, 153, 248, 188, 240, 195, 131, 36, 232, 96, 92, 40]
         let expected:[UInt8] = [103, 238, 5, 84, 116, 153, 248, 188, 240, 195, 131, 36, 232, 96, 92, 40]
         
         
-        if let aes = AES(key: key, iv:iv, blockMode: .CTR) {
-            XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode")
-            let encrypted = try! aes.encrypt(plaintext, padding: nil)
-            XCTAssertEqual(encrypted, expected, "encryption failed")
-            let decrypted = try! aes.decrypt(encrypted, padding: nil)
-            XCTAssertEqual(decrypted, plaintext, "decryption failed")
-        } else {
-            XCTAssert(false, "failed")
-        }
+        let aes = try! AES(key: key, iv:iv, blockMode: .CTR)
+        XCTAssertTrue(aes.blockMode == .CTR, "Invalid block mode")
+        let encrypted = try! aes.encrypt(plaintext, padding: nil)
+        XCTAssertEqual(encrypted, expected, "encryption failed")
+        let decrypted = try! aes.decrypt(encrypted, padding: nil)
+        XCTAssertEqual(decrypted, plaintext, "decryption failed")
     }
     }
     
     
     func testAES_encrypt_performance() {
     func testAES_encrypt_performance() {
         let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
         let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
         let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
         let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
         let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
         let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
-        let aes = AES(key: key, iv: iv, blockMode: .CBC)
+        let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
         measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
         measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
-            try! aes?.encrypt(message, padding: PKCS7())
+            try! aes.encrypt(message, padding: PKCS7())
         })
         })
     }
     }
 
 
@@ -132,9 +141,9 @@ final class AESTests: XCTestCase {
         let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
         let key:[UInt8] = [0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c];
         let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
         let iv:[UInt8] = [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F]
         let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
         let message = [UInt8](count: 1024 * 1024, repeatedValue: 7)
-        let aes = AES(key: key, iv: iv, blockMode: .CBC)
+        let aes = try! AES(key: key, iv: iv, blockMode: .CBC)
         measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
         measureMetrics([XCTPerformanceMetric_WallClockTime], automaticallyStartMeasuring: true, forBlock: { () -> Void in
-            try! aes?.decrypt(message, padding: PKCS7())
+            try! aes.decrypt(message, padding: PKCS7())
         })
         })
     }
     }
 
 

+ 5 - 5
CryptoSwiftTests/ChaCha20Tests.swift

@@ -50,18 +50,18 @@ final class ChaCha20Tests: XCTestCase {
             
             
             let setup = (key: keys[idx], iv: ivs[idx])
             let setup = (key: keys[idx], iv: ivs[idx])
             do {
             do {
-                let encrypted = try Cipher.ChaCha20(setup).encrypt(message)
-                let decrypted = try Cipher.ChaCha20(setup).decrypt(encrypted)
+                let encrypted = try ChaCha20(setup)!.encrypt(message)
+                let decrypted = try ChaCha20(setup)!.decrypt(encrypted)
                 XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
                 XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
                 
                 
                 // check extension
                 // check extension
                 let messageData = NSData(bytes: message, length: message.count);
                 let messageData = NSData(bytes: message, length: message.count);
-                let encrypted2 = try! messageData.encrypt(Cipher.ChaCha20(setup))
+                let encrypted2 = try! messageData.encrypt(ChaCha20(setup)!)
                 XCTAssertNotNil(encrypted2, "")
                 XCTAssertNotNil(encrypted2, "")
                 XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
                 XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
-            } catch Cipher.Error.EncryptError {
+            } catch CipherError.Encrypt {
                 XCTAssert(false, "Encryption failed")
                 XCTAssert(false, "Encryption failed")
-            } catch Cipher.Error.DecryptError {
+            } catch CipherError.Decrypt {
                 XCTAssert(false, "Decryption failed")
                 XCTAssert(false, "Decryption failed")
             } catch {
             } catch {
                 XCTAssert(false, "Failed")
                 XCTAssert(false, "Failed")

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov