Bladeren bron

Electronic codebook (ECB)

Marcin Krzyżanowski 10 jaren geleden
bovenliggende
commit
147aa13d9f
4 gewijzigde bestanden met toevoegingen van 45 en 10 verwijderingen
  1. 8 0
      CryptoSwift/AES.swift
  2. 18 9
      CryptoSwift/CipherBlockMode.swift
  3. 18 1
      CryptoSwiftTests/AESTests.swift
  4. 1 0
      README.md

+ 8 - 0
CryptoSwift/AES.swift

@@ -98,6 +98,14 @@ public class AES {
         self.iv = iv
         self.blockMode = blockMode
         
+//        if (blockMode.supportIV() && iv == nil) {
+//            // auto generate IV
+//            var generatedIV:[Byte] = [Byte]();
+//            for (var i = 0; i < key.length; i++) {
+//                generatedIV.append(UInt8(truncatingBitPattern: arc4random_uniform(256)));
+//            }
+//        }
+        
         switch (key.length * 8) {
         case 128:
             self.variant = .aes128

+ 18 - 9
CryptoSwift/CipherBlockMode.swift

@@ -9,7 +9,16 @@
 import Foundation
 
 public enum CipherBlockMode {
-    case Plain, CBC, CFB
+    case ECB, CBC, CFB
+    
+    func supportIV() -> Bool {
+        switch (self) {
+        case CBC, CFB:
+            return true
+        default:
+            return false
+        }
+    }
     
     /**
     Process input blocks with given block cipher mode. With fallback to plain mode.
@@ -25,7 +34,7 @@ public enum CipherBlockMode {
         // if IV is not available, fallback to plain
         var finalBlockMode:CipherBlockMode = self
         if (iv == nil) {
-            finalBlockMode = .Plain
+            finalBlockMode = .ECB
         }
         
         switch (finalBlockMode) {
@@ -33,8 +42,8 @@ public enum CipherBlockMode {
             return CBCMode.encryptBlocks(blocks, iv: iv, cipher: cipher)
         case CFB:
             return CFBMode.encryptBlocks(blocks, iv: iv, cipher: cipher)
-        case Plain:
-            return PlainMode.encryptBlocks(blocks, cipher: cipher)
+        case ECB:
+            return ECBMode.encryptBlocks(blocks, cipher: cipher)
         }
     }
     
@@ -42,7 +51,7 @@ public enum CipherBlockMode {
         // if IV is not available, fallback to plain
         var finalBlockMode:CipherBlockMode = self
         if (iv == nil) {
-            finalBlockMode = .Plain
+            finalBlockMode = .ECB
         }
         
         switch (finalBlockMode) {
@@ -50,8 +59,8 @@ public enum CipherBlockMode {
             return CBCMode.decryptBlocks(blocks, iv: iv, cipher: cipher)
         case CFB:
             return CFBMode.decryptBlocks(blocks, iv: iv, cipher: cipher)
-        case Plain:
-            return PlainMode.decryptBlocks(blocks, cipher: cipher)
+        case ECB:
+            return ECBMode.decryptBlocks(blocks, cipher: cipher)
         }
     }
 }
@@ -182,9 +191,9 @@ private struct CFBMode {
 
 
 /**
-*  Plain mode, don't use it. For debuging purposes only
+*  Electronic codebook (ECB)
 */
-private struct PlainMode {
+private struct ECBMode {
     static func encryptBlocks(blocks:[[Byte]], cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
         var out:[Byte]?
         for (idx,plaintext) in enumerate(blocks) {

+ 18 - 1
CryptoSwiftTests/AESTests.swift

@@ -14,6 +14,23 @@ class AESTests: XCTestCase {
     // 128 bit key
     let aesKey:[Byte] = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]
 
+    func testAES_encrypt2() {
+        let key:[Byte]   = [0x36, 0x37, 0x39, 0x66, 0x62, 0x31, 0x64, 0x64, 0x66, 0x37, 0x64, 0x38, 0x31, 0x62, 0x65, 0x65];
+        let iv:[Byte]    = [0x6b, 0x64, 0x66, 0x36, 0x37, 0x33, 0x39, 0x38, 0x44, 0x46, 0x37, 0x33, 0x38, 0x33, 0x66, 0x64]
+        let input:[Byte] = [0x62, 0x72, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+        
+        let expected:[Byte] = [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))
+            XCTAssertEqual(encrypted!, NSData.withBytes(expected), "encryption failed")
+            let decrypted = aes.decrypt(encrypted!)
+            XCTAssertEqual(decrypted!, NSData.withBytes(input), "decryption failed")
+        } else {
+            XCTAssert(false, "failed")
+        }
+    }
+
     func testAES_encrypt() {
         let input:[Byte] = [0x00, 0x11, 0x22, 0x33,
             0x44, 0x55, 0x66, 0x77,
@@ -25,7 +42,7 @@ class AESTests: XCTestCase {
             0xd8, 0xcd, 0xb7, 0x80,
             0x70, 0xb4, 0xc5, 0x5a];
         
-        if let aes = AES(key: NSData.withBytes(aesKey), iv: nil, blockMode: .Plain) {
+        if let aes = AES(key: NSData.withBytes(aesKey), iv: nil, blockMode: .ECB) {
             let encrypted = aes.encrypt(NSData.withBytes(input))
             XCTAssertEqual(encrypted!, NSData.withBytes(expected), "encryption failed")
             let decrypted = aes.decrypt(encrypted!)

+ 1 - 0
README.md

@@ -28,6 +28,7 @@ Good mood
 - [Poly1305](http://cr.yp.to/mac/poly1305-20050329.pdf)
 
 #####Cipher block mode
+- Electronic codebook ([ECB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29))
 - Cipher-block chaining ([CBC](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29))
 - Cipher feedback ([CFB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_.28CFB.29))