瀏覽代碼

Use bitPadding(..) in place of shared prepare()

Marcin Krzyżanowski 9 年之前
父節點
當前提交
c411561c51

+ 4 - 0
CHANGELOG

@@ -1,3 +1,7 @@
+0.6.0-beta2
+- SHA-2 fix #319
+- HashProtocol -> Digest and refactor
+
 0.6.0-beta1
 - Swift 3 compatibility
 - Multiplatform, Single-scheme Xcode Project

+ 4 - 4
CryptoSwift.xcodeproj/project.pbxproj

@@ -37,7 +37,7 @@
 		757BC9681C1CA5790093AAA9 /* CSArrayType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9251C1CA5790093AAA9 /* CSArrayType+Extensions.swift */; };
 		757BC96C1C1CA5790093AAA9 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9261C1CA5790093AAA9 /* Generics.swift */; };
 		757BC9701C1CA5790093AAA9 /* Hash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9271C1CA5790093AAA9 /* Hash.swift */; };
-		757BC9741C1CA5790093AAA9 /* HashProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9281C1CA5790093AAA9 /* HashProtocol.swift */; };
+		757BC9741C1CA5790093AAA9 /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9281C1CA5790093AAA9 /* Digest.swift */; };
 		757BC9781C1CA5790093AAA9 /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC9291C1CA5790093AAA9 /* HMAC.swift */; };
 		757BC9801C1CA5790093AAA9 /* IntegerConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC92B1C1CA5790093AAA9 /* IntegerConvertible.swift */; };
 		757BC9841C1CA5790093AAA9 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757BC92C1C1CA5790093AAA9 /* Int+Extension.swift */; };
@@ -184,7 +184,7 @@
 		757BC9251C1CA5790093AAA9 /* CSArrayType+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "CSArrayType+Extensions.swift"; path = "Sources/CryptoSwift/CSArrayType+Extensions.swift"; sourceTree = SOURCE_ROOT; };
 		757BC9261C1CA5790093AAA9 /* Generics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Generics.swift; path = Sources/CryptoSwift/Generics.swift; sourceTree = SOURCE_ROOT; };
 		757BC9271C1CA5790093AAA9 /* Hash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Hash.swift; path = Sources/CryptoSwift/Hash.swift; sourceTree = SOURCE_ROOT; };
-		757BC9281C1CA5790093AAA9 /* HashProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HashProtocol.swift; path = Sources/CryptoSwift/HashProtocol.swift; sourceTree = SOURCE_ROOT; };
+		757BC9281C1CA5790093AAA9 /* Digest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Digest.swift; path = Sources/CryptoSwift/Digest.swift; sourceTree = SOURCE_ROOT; };
 		757BC9291C1CA5790093AAA9 /* HMAC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HMAC.swift; path = Sources/CryptoSwift/HMAC.swift; sourceTree = SOURCE_ROOT; };
 		757BC92A1C1CA5790093AAA9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sources/CryptoSwift/Info.plist; sourceTree = SOURCE_ROOT; };
 		757BC92B1C1CA5790093AAA9 /* IntegerConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntegerConvertible.swift; path = Sources/CryptoSwift/IntegerConvertible.swift; sourceTree = SOURCE_ROOT; };
@@ -301,7 +301,7 @@
 				757BC9231C1CA5790093AAA9 /* Checksum.swift */,
 				757BC9261C1CA5790093AAA9 /* Generics.swift */,
 				757BC9271C1CA5790093AAA9 /* Hash.swift */,
-				757BC9281C1CA5790093AAA9 /* HashProtocol.swift */,
+				757BC9281C1CA5790093AAA9 /* Digest.swift */,
 				757BC9291C1CA5790093AAA9 /* HMAC.swift */,
 				757BC92B1C1CA5790093AAA9 /* IntegerConvertible.swift */,
 				757BC92D1C1CA5790093AAA9 /* MD5.swift */,
@@ -546,7 +546,7 @@
 				757BC9C01C1CA5790093AAA9 /* Utils.swift in Sources */,
 				75CB93491C8F60700087740D /* ECB.swift in Sources */,
 				757F440E1CC1822B002B1F85 /* SecureBytes.swift in Sources */,
-				757BC9741C1CA5790093AAA9 /* HashProtocol.swift in Sources */,
+				757BC9741C1CA5790093AAA9 /* Digest.swift in Sources */,
 				750D3ACB1D0EADCA00999299 /* ZeroPadding.swift in Sources */,
 				756B575F1D5131A4001C0C72 /* Collection+Extension.swift in Sources */,
 				757BC90E1C1CA56A0093AAA9 /* Rabbit+Foundation.swift in Sources */,

+ 2 - 33
Sources/CryptoSwift/Digest.swift

@@ -1,40 +1,9 @@
 //
-//  HashProtocol.swift
+//  Digest.swift
 //  CryptoSwift
 //
 //  Created by Marcin Krzyzanowski on 17/08/14.
 //  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
 //
 
-internal protocol HashProtocol: class {
-    var message: Array<UInt8> { get }
-    
-    /** Common part for hash calculation. Prepare header data. */
-    func prepare(_ len:Int) -> Array<UInt8>
-}
-
-extension HashProtocol {
-    
-    func prepare(_ len:Int) -> Array<UInt8> {
-        return self.prepare(len, allowance: len / 8)
-    }
-    
-    func prepare(_ len:Int, allowance: Int) -> Array<UInt8> {
-        var tmpMessage = message
-        
-        // Step 1. Append Padding Bits
-        tmpMessage.append(0x80) // append one bit (UInt8 with one bit) to message
-        
-        // append "0" bit until message length in bits ≡ 448 (mod 512)
-        var msgLength = tmpMessage.count
-        var counter = 0
-        
-        while msgLength % len != (len - allowance) {
-            counter += 1
-            msgLength += 1
-        }
-        
-        tmpMessage += Array<UInt8>(repeating: 0, count: counter)
-        return tmpMessage
-    }
-}
+internal protocol Digest { }

+ 2 - 0
Sources/CryptoSwift/HMAC.swift

@@ -68,6 +68,7 @@ final public class HMAC: Authenticator {
             }
         }
 
+        //TODO: validate 64 bytes long key
         self.key = ZeroPadding().add(to: key, blockSize: variant.blockSize())
     }
 
@@ -89,6 +90,7 @@ final public class HMAC: Authenticator {
             throw Error.authenticateError
         }
 
+        // return Array(result[0..<10]) // 80 bits
         return result
     }
 }

+ 2 - 2
Sources/CryptoSwift/MD5.swift

@@ -6,7 +6,7 @@
 //  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
 //
 
-final class MD5 : HashProtocol  {
+final class MD5 : Digest  {
     static let size:Int = 16 // 128 / 8
     let message: Array<UInt8>
     
@@ -41,7 +41,7 @@ final class MD5 : HashProtocol  {
     private let h:Array<UInt32> = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]
     
     func calculate() -> Array<UInt8> {
-        var tmpMessage = prepare(64)
+        var tmpMessage = bitPadding(to: self.message, blockSize: 64, allowance: 64 / 8)
         tmpMessage.reserveCapacity(tmpMessage.count + 4)
 
         // initialize hh with hash values

+ 2 - 2
Sources/CryptoSwift/SHA1.swift

@@ -6,7 +6,7 @@
 //  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
 //
 
-final class SHA1 : HashProtocol {
+final class SHA1 : Digest {
     static let size:Int = 20 // 160 / 8
     let message: Array<UInt8>
     
@@ -17,7 +17,7 @@ final class SHA1 : HashProtocol {
     private let h:Array<UInt32> = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
         
     func calculate() -> Array<UInt8> {
-        var tmpMessage = self.prepare(64)
+        var tmpMessage = bitPadding(to: self.message, blockSize: 64, allowance: 64 / 8)
         
         // hash values
         var hh = h

+ 4 - 4
Sources/CryptoSwift/SHA2.swift

@@ -6,7 +6,7 @@
 //  Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
 //
 
-final class SHA2 : HashProtocol {
+final class SHA2 : Digest {
     var size:Int { return variant.rawValue }
     let variant: Variant
     
@@ -114,8 +114,8 @@ final class SHA2 : HashProtocol {
     
     //FIXME: I can't do Generic func out of calculate32 and calculate64 (UInt32 vs UInt64), but if you can - please do pull request.
     func calculate32() -> Array<UInt8> {
-        var tmpMessage = self.prepare(64)
-        
+        var tmpMessage = bitPadding(to: self.message, blockSize: 64, allowance: 64 / 8)
+
         // hash values
         var hh = Array<UInt32>()
         variant.h.forEach {(h) -> () in
@@ -196,7 +196,7 @@ final class SHA2 : HashProtocol {
     }
     
     func calculate64() -> Array<UInt8> {
-        var tmpMessage = self.prepare(128, allowance: 16)
+        var tmpMessage = bitPadding(to: self.message, blockSize: 128, allowance: 128 / 8)
         
         // hash values
         var hh = Array<UInt64>()

+ 27 - 0
Sources/CryptoSwift/Utils.swift

@@ -59,3 +59,30 @@ func xor(_ a: Array<UInt8>, _ b:Array<UInt8>) -> Array<UInt8> {
     }
     return xored
 }
+
+/**
+ ISO/IEC 9797-1 Padding method 2.
+ Add a single bit with value 1 to the end of the data.
+ If necessary add bits with value 0 to the end of the data until the padded data is a multiple of blockSize.
+ - parameters:
+ - blockSize: Padding size in bytes.
+ - allowance: Excluded trailing number of bytes.
+ */
+func bitPadding(to data: Array<UInt8>, blockSize: Int, allowance: Int = 0) -> Array<UInt8> {
+    var tmp = data
+
+    // Step 1. Append Padding Bits
+    tmp.append(0x80) // append one bit (UInt8 with one bit) to message
+
+    // append "0" bit until message length in bits ≡ 448 (mod 512)
+    var msgLength = tmp.count
+    var counter = 0
+
+    while msgLength % blockSize != (blockSize - allowance) {
+        counter += 1
+        msgLength += 1
+    }
+
+    tmp += Array<UInt8>(repeating: 0, count: counter)
+    return tmp
+}