Browse Source

Massive internal change NSData to [UInt8]

Marcin Krzyżanowski 10 years ago
parent
commit
9f4527f79d

+ 14 - 18
CryptoSwift/AES.swift

@@ -114,7 +114,7 @@ public class AES {
         }
         
         if (blockMode.requireIV() && iv.length != AES.blockSizeBytes()) {
-            assertionFailure("Block size and Initialization Vector must be the same length!")
+            assert(false, "Block size and Initialization Vector must be the same length!")
             return nil
         }
     }
@@ -128,10 +128,6 @@ public class AES {
     public class func blockSizeBytes() -> Int {
         return 128 / 8 // 16 bytes
     }
-    
-    public class func blockSizeBytes() -> UInt8 {
-        return UInt8(truncatingBitPattern: self.blockSizeBytes())
-    }
 
     /**
     Encrypt message. If padding is necessary, then PKCS7 padding is addedd and need to be removed after decryption.
@@ -141,20 +137,19 @@ public class AES {
     :returns: Encrypted data
     */
 
-    public func encrypt(message:NSData, padding: Padding? = PKCS7()) -> NSData? {
-        var finalMessage = message;
+    public func encrypt(bytes:[UInt8], padding: Padding? = PKCS7()) -> [UInt8]? {
+        var finalBytes = bytes;
 
         if let padding = padding {
-            finalMessage = padding.add(message, blockSize: AES.blockSizeBytes())
-        } else if (message.length % AES.blockSizeBytes() != 0) {
+            finalBytes = padding.add(bytes, blockSize: AES.blockSizeBytes())
+        } else if (bytes.count % AES.blockSizeBytes() != 0) {
             // 128 bit block exceeded, need padding
             assert(false, "AES 128-bit block exceeded!");
             return nil
         }
         
-        let blocks = finalMessage.bytes().chunks(AES.blockSizeBytes())
-        let out = blockMode.encryptBlocks(blocks, iv: self.iv?.bytes(), cipher: encryptBlock)
-        return out == nil ? nil : NSData.withBytes(out!)
+        let blocks = finalBytes.chunks(AES.blockSizeBytes())
+        return blockMode.encryptBlocks(blocks, iv: self.iv?.bytes(), cipher: encryptBlock)
     }
     
     private func encryptBlock(block:[UInt8]) -> [UInt8]? {
@@ -190,14 +185,15 @@ public class AES {
         return out
     }
     
-    public func decrypt(message:NSData, removePadding:Bool = true) -> NSData? {
-        if (message.length % AES.blockSizeBytes() != 0) {
+    //TODO: Padding
+    public func decrypt(bytes:[UInt8], removePadding:Bool) -> [UInt8]? {
+        if (bytes.count % AES.blockSizeBytes() != 0) {
             // 128 bit block exceeded
-            assertionFailure("AES 128-bit block exceeded!")
+            assert(false,"AES 128-bit block exceeded!")
             return nil
         }
         
-        let blocks = message.bytes().chunks(AES.blockSizeBytes())
+        let blocks = bytes.chunks(AES.blockSizeBytes())
         var out:[UInt8]?
         if (blockMode == .CFB) {
             // CFB uses encryptBlock to decrypt
@@ -207,10 +203,10 @@ public class AES {
         }
         
         if (out != nil && removePadding) {
-            return PKCS7().remove(NSData.withBytes(out!))
+            return PKCS7().remove(out!)
         }
         
-        return out == nil ? nil : NSData.withBytes(out!)
+        return out;
     }
     
     private func decryptBlock(block:[UInt8]) -> [UInt8]? {

+ 6 - 6
CryptoSwift/Cipher.swift

@@ -36,14 +36,14 @@ public enum Cipher {
     
     :returns: encrypted message
     */
-    public func encrypt(message: NSData) -> NSData? {
+    public func encrypt(bytes: [UInt8]) -> [UInt8]? {
         switch (self) {
             case .ChaCha20(let key, let iv):
                 var chacha = CryptoSwift.ChaCha20(key: key, iv: iv)
-                return chacha?.encrypt(message)
+                return chacha?.encrypt(NSData.withBytes(bytes))?.bytes() //TODO: [UInt8]
             case .AES(let key, let iv, let blockMode):
                 var aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode)
-                return aes?.encrypt(message, padding: PKCS7())
+                return aes?.encrypt(bytes, padding: PKCS7())
         }
     }
     
@@ -54,14 +54,14 @@ public enum Cipher {
     
     :returns: Plaintext message
     */
-    public func decrypt(message: NSData) -> NSData? {
+    public func decrypt(bytes: [UInt8]) -> [UInt8]? {
         switch (self) {
             case .ChaCha20(let key, let iv):
                 var chacha = CryptoSwift.ChaCha20(key: key, iv: iv);
-                return chacha?.decrypt(message)
+                return chacha?.decrypt(NSData.withBytes(bytes))?.bytes() //TODO: [UInt8]
             case .AES(let key, let iv, let blockMode):
                 var aes = CryptoSwift.AES(key: key, iv: iv, blockMode: blockMode);
-                return aes?.decrypt(message)
+                return aes?.decrypt(bytes, removePadding: true)
         }
     }
 

+ 8 - 2
CryptoSwift/NSDataExtension.swift

@@ -61,11 +61,17 @@ extension NSData {
     }
 
     public func encrypt(cipher: Cipher) -> NSData? {
-        return cipher.encrypt(self)
+        if let encrypted = cipher.encrypt(self.bytes()) {
+            return NSData.withBytes(encrypted)
+        }
+        return nil
     }
 
     public func decrypt(cipher: Cipher) -> NSData? {
-        return cipher.decrypt(self)
+        if let decrypted = cipher.decrypt(self.bytes()) {
+            return NSData.withBytes(decrypted)
+        }
+        return nil;
     }
     
     public func authenticate(authenticator: Authenticator) -> NSData? {

+ 10 - 12
CryptoSwift/PKCS7.swift

@@ -14,31 +14,29 @@ public struct PKCS7: Padding {
         
     }
     
-    public func add(data: NSData , blockSize:Int) -> NSData {
-        var padding = UInt8(blockSize) - (UInt8(data.length) % UInt8(blockSize))
-        var withPadding = NSMutableData(data: data)
+    public func add(bytes: [UInt8] , blockSize:Int) -> [UInt8] {
+        var padding = UInt8(blockSize) - (UInt8(bytes.count) % UInt8(blockSize))
+        var withPadding = bytes
         if (padding == 0) {
             // If the original data is a multiple of N bytes, then an extra block of bytes with value N is added.
             for i in 0..<blockSize {
-                withPadding.appendBytes([UInt8(blockSize)])
+                withPadding += [UInt8(blockSize)]
             }
         } else {
             // The value of each added byte is the number of bytes that are added
             for i in 0..<padding {
-                withPadding.appendBytes([padding])
+                withPadding += [UInt8(padding)]
             }
         }
         return withPadding
     }
     
-    public func remove(data: NSData, blockSize:Int? = nil) -> NSData
-    {
-        var padding:UInt8 = 0
-        data.subdataWithRange(NSRange(location: data.length - 1, length: 1)).getBytes(&padding, length: 1)
+    public func remove(bytes: [UInt8], blockSize:Int? = nil) -> [UInt8] {
+        var padding = Int(bytes.last!) // last byte
         
-        if padding >= 1 {
-            return data.subdataWithRange(NSRange(location: 0, length: data.length - Int(padding)))
+        if padding >= 1 { //TODO: need test for that, what about empty padding
+            return Array(bytes[0..<(bytes.count - padding)])
         }
-        return data
+        return bytes
     }
 }

+ 2 - 2
CryptoSwift/Padding.swift

@@ -9,6 +9,6 @@
 import Foundation
 
 public protocol Padding {
-    func add(data: NSData, blockSize:Int) -> NSData;
-    func remove(data: NSData, blockSize:Int?) -> NSData;
+    func add(data: [UInt8], blockSize:Int) -> [UInt8];
+    func remove(data: [UInt8], blockSize:Int?) -> [UInt8];
 }

+ 1 - 1
CryptoSwift/Playground/CryptoPlayground.playground/section-1.swift

@@ -30,4 +30,4 @@ func testtest() {
     println(t.foo())
 }
 
-testtest()
+testtest()

+ 13 - 13
CryptoSwiftTests/AESTests.swift

@@ -22,10 +22,10 @@ class AESTests: XCTestCase {
         let expected:[UInt8] = [0xae,0x8c,0x59,0x95,0xb2,0x6f,0x8e,0x3d,0xb0,0x6f,0x0a,0xa5,0xfe,0xc4,0xf0,0xc2];
         
         if let aes = AES(key: NSData.withBytes(key), iv: NSData.withBytes(iv), blockMode: .CBC) {
-            let encrypted = aes.encrypt(NSData.withBytes(input), padding: nil)
-            XCTAssertEqual(encrypted!, NSData.withBytes(expected), "encryption failed")
-            let decrypted = aes.decrypt(encrypted!)
-            XCTAssertEqual(decrypted!, NSData.withBytes(input), "decryption failed")
+            let encrypted = aes.encrypt(input, padding: nil)
+            XCTAssertEqual(encrypted!, expected, "encryption failed")
+            let decrypted = aes.decrypt(encrypted!, removePadding: true)
+            XCTAssertEqual(decrypted!, input, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -43,10 +43,10 @@ class AESTests: XCTestCase {
             0x70, 0xb4, 0xc5, 0x5a];
         
         if let aes = AES(key: NSData.withBytes(aesKey), blockMode: .ECB) {
-            let encrypted = aes.encrypt(NSData.withBytes(input), padding: nil)
-            XCTAssertEqual(encrypted!, NSData.withBytes(expected), "encryption failed")
+            let encrypted = aes.encrypt(input, padding: nil)
+            XCTAssertEqual(encrypted!, expected, "encryption failed")
             let decrypted = aes.decrypt(encrypted!, removePadding: false)
-            XCTAssertEqual(decrypted!, NSData.withBytes(input), "decryption failed")
+            XCTAssertEqual(decrypted!, input, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -60,10 +60,10 @@ class AESTests: XCTestCase {
         
         if let aes = AES(key: NSData.withBytes(key), iv:NSData.withBytes(iv), blockMode: .CBC) {
             XCTAssertTrue(aes.blockMode == .CBC, "Invalid block mode")
-            let encrypted = aes.encrypt(NSData.withBytes(plaintext), padding: nil)
-            XCTAssertEqual(encrypted!, NSData.withBytes(expected), "encryption failed")
+            let encrypted = aes.encrypt(plaintext, padding: nil)
+            XCTAssertEqual(encrypted!, expected, "encryption failed")
             let decrypted = aes.decrypt(encrypted!, removePadding: false)
-            XCTAssertEqual(decrypted!, NSData.withBytes(plaintext), "decryption failed")
+            XCTAssertEqual(decrypted!, plaintext, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }
@@ -77,10 +77,10 @@ class AESTests: XCTestCase {
         
         if let aes = AES(key: NSData.withBytes(key), iv:NSData.withBytes(iv), blockMode: .CFB) {
             XCTAssertTrue(aes.blockMode == .CFB, "Invalid block mode")
-            let encrypted = aes.encrypt(NSData.withBytes(plaintext), padding: nil)
-            XCTAssertEqual(encrypted!, NSData.withBytes(expected), "encryption failed")
+            let encrypted = aes.encrypt(plaintext, padding: nil)
+            XCTAssertEqual(encrypted!, expected, "encryption failed")
             let decrypted = aes.decrypt(encrypted!, removePadding: false)
-            XCTAssertEqual(decrypted!, NSData.withBytes(plaintext), "decryption failed")
+            XCTAssertEqual(decrypted!, plaintext, "decryption failed")
         } else {
             XCTAssert(false, "failed")
         }

+ 6 - 6
CryptoSwiftTests/ChaCha20Tests.swift

@@ -52,23 +52,23 @@ class ChaCha20Tests: XCTestCase {
             let expectedHex = expectedHexes[idx]
             //println(countElements(expectedHex) / 2);
             let message = [UInt8](count: (count(expectedHex) / 2), repeatedValue: 0)
-            let messageData = NSData(bytes: message, length: message.count);
             
             let setup = (key: keyData, iv: ivData)
-            var encrypted = Cipher.ChaCha20(setup).encrypt(messageData)
-            XCTAssertNotNil(encrypted, "")
+            var encrypted = Cipher.ChaCha20(setup).encrypt(message)
+            XCTAssert(encrypted != nil, "missing")
             if let encrypted = encrypted {
                 var decrypted = Cipher.ChaCha20(setup).decrypt(encrypted)
-                XCTAssertNotNil(decrypted, "")
+                XCTAssert(decrypted != nil, "missing")
                 if let decrypted = decrypted {
-                    XCTAssertEqual(messageData, decrypted, "ChaCha20 decryption failed");
+                    XCTAssertEqual(message, decrypted, "ChaCha20 decryption failed");
                 }
                 
                 // check extension
+                let messageData = NSData(bytes: message, length: message.count);
                 let encrypted2 = messageData.encrypt(Cipher.ChaCha20(setup))
                 XCTAssertNotNil(encrypted2, "")
                 if let encrypted2 = encrypted2 {
-                    XCTAssertEqual(encrypted, encrypted2, "ChaCha20 extension failed")
+                    XCTAssertEqual(NSData.withBytes(encrypted), encrypted2, "ChaCha20 extension failed")
                 }
             }
         }

+ 9 - 9
CryptoSwiftTests/PaddingTests.swift

@@ -14,27 +14,27 @@ class PaddingTests: XCTestCase {
     func testPKCS7_0() {
         let input:[UInt8]    = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]
         let expected:[UInt8] = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16]
-        let padded = PKCS7().add(NSData.withBytes(input), blockSize: 16)
-        XCTAssertEqual(padded, NSData.withBytes(expected), "PKCS7 failed")
+        let padded = PKCS7().add(input, blockSize: 16)
+        XCTAssertEqual(padded, expected, "PKCS7 failed")
         let clean = PKCS7().remove(padded)
-        XCTAssertEqual(clean, NSData.withBytes(input), "PKCS7 failed")
+        XCTAssertEqual(clean, input, "PKCS7 failed")
     }
     
     func testPKCS7_1() {
         let input:[UInt8]    = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]
         let expected:[UInt8] = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,1]
-        let padded = PKCS7().add(NSData.withBytes(input), blockSize: 16)
-        XCTAssertEqual(padded, NSData.withBytes(expected), "PKCS7 failed")
+        let padded = PKCS7().add(input, blockSize: 16)
+        XCTAssertEqual(padded, expected, "PKCS7 failed")
         let clean = PKCS7().remove(padded)
-        XCTAssertEqual(clean, NSData.withBytes(input), "PKCS7 failed")
+        XCTAssertEqual(clean, input, "PKCS7 failed")
     }
     
     func testPKCS7_2() {
         let input:[UInt8]    = [1,2,3,4,5,6,7,8,9,0,1,2,3,4]
         let expected:[UInt8] = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,2,2]
-        let padded = PKCS7().add(NSData.withBytes(input), blockSize: 16)
-        XCTAssertEqual(padded, NSData.withBytes(expected), "PKCS7 failed")
+        let padded = PKCS7().add(input, blockSize: 16)
+        XCTAssertEqual(padded, expected, "PKCS7 failed")
         let clean = PKCS7().remove(padded)
-        XCTAssertEqual(clean, NSData.withBytes(input), "PKCS7 failed")
+        XCTAssertEqual(clean, input, "PKCS7 failed")
     }
 }