diff --git a/Sources/Cryptor/Digest.swift b/Sources/Cryptor/Digest.swift index 5411256..7377f8c 100755 --- a/Sources/Cryptor/Digest.swift +++ b/Sources/Cryptor/Digest.swift @@ -17,7 +17,7 @@ import Foundation -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL @@ -87,56 +87,56 @@ public class Digest: Updatable { switch algorithm { case .md2: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_MD2_Init, updater:CC_MD2_Update, finalizer:CC_MD2_Final, length:CC_MD2_DIGEST_LENGTH) #elseif os(Linux) fatalError("MD2 digest not supported by OpenSSL") #endif case .md4: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_MD4_Init, updater:CC_MD4_Update, finalizer:CC_MD4_Final, length:CC_MD4_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer:MD4_Init, updater:MD4_Update, finalizer:MD4_Final, length:MD4_DIGEST_LENGTH) #endif case .md5: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_MD5_Init, updater:CC_MD5_Update, finalizer:CC_MD5_Final, length:CC_MD5_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer:MD5_Init, updater:MD5_Update, finalizer:MD5_Final, length:MD5_DIGEST_LENGTH) #endif case .sha1: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_SHA1_Init, updater:CC_SHA1_Update, finalizer:CC_SHA1_Final, length:CC_SHA1_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer:SHA1_Init, updater:SHA1_Update, finalizer:SHA1_Final, length:SHA_DIGEST_LENGTH) #endif case .sha224: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_SHA224_Init, updater:CC_SHA224_Update, finalizer:CC_SHA224_Final, length:CC_SHA224_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer:SHA224_Init, updater:SHA224_Update, finalizer:SHA224_Final, length:SHA224_DIGEST_LENGTH) #endif case .sha256: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_SHA256_Init, updater:CC_SHA256_Update, finalizer:CC_SHA256_Final, length:CC_SHA256_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer: SHA256_Init, updater:SHA256_Update, finalizer:SHA256_Final, length:SHA256_DIGEST_LENGTH) #endif case .sha384: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_SHA384_Init, updater:CC_SHA384_Update, finalizer:CC_SHA384_Final, length:CC_SHA384_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer:SHA384_Init, updater:SHA384_Update, finalizer:SHA384_Final, length:SHA384_DIGEST_LENGTH) #endif case .sha512: - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) engine = DigestEngineCC(initializer:CC_SHA512_Init, updater:CC_SHA512_Update, finalizer:CC_SHA512_Final, length:CC_SHA512_DIGEST_LENGTH) #elseif os(Linux) engine = DigestEngineCC(initializer:SHA512_Init, updater:SHA512_Update, finalizer:SHA512_Final, length:SHA512_DIGEST_LENGTH) diff --git a/Sources/Cryptor/HMAC.swift b/Sources/Cryptor/HMAC.swift index 086cd62..51d385b 100755 --- a/Sources/Cryptor/HMAC.swift +++ b/Sources/Cryptor/HMAC.swift @@ -17,7 +17,7 @@ import Foundation -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL @@ -51,8 +51,8 @@ public class HMAC: Updatable { /// Secure Hash Algorithm 2 512-bit case sha512 - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + static let fromNative: [CCHmacAlgorithm: Algorithm] = [ CCHmacAlgorithm(kCCHmacAlgSHA1): .sha1, CCHmacAlgorithm(kCCHmacAlgSHA1): .md5, @@ -114,8 +114,8 @@ public class HMAC: Updatable { /// public func digestLength() -> Int { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + switch self { case .sha1: @@ -156,8 +156,8 @@ public class HMAC: Updatable { } /// Context - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + typealias Context = UnsafeMutablePointer #elseif os(Linux) @@ -189,7 +189,7 @@ public class HMAC: Updatable { init(using algorithm: Algorithm, keyBuffer: UnsafeRawPointer, keyByteCount: Int) { self.algorithm = algorithm - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) CCHmacInit(context, algorithm.nativeValue(), keyBuffer, size_t(keyByteCount)) #elseif os(Linux) HMAC_Init_wrapper(context, keyBuffer, Int32(keyByteCount), .make(optional: algorithm.nativeValue())) @@ -207,7 +207,7 @@ public class HMAC: Updatable { self.algorithm = algorithm #if swift(>=5.0) - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) key.withUnsafeBytes() { CCHmacInit(context, algorithm.nativeValue(), $0.baseAddress, size_t(key.count)) } @@ -217,7 +217,7 @@ public class HMAC: Updatable { } #endif #else - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) key.withUnsafeBytes() { (buffer: UnsafePointer) in CCHmacInit(context, algorithm.nativeValue(), buffer, size_t(key.count)) } @@ -239,7 +239,7 @@ public class HMAC: Updatable { public init(using algorithm: Algorithm, key: NSData) { self.algorithm = algorithm - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) CCHmacInit(context, algorithm.nativeValue(), key.bytes, size_t(key.length)) #elseif os(Linux) HMAC_Init_wrapper(context, key.bytes, Int32(key.length), .make(optional: algorithm.nativeValue())) @@ -256,7 +256,7 @@ public class HMAC: Updatable { public init(using algorithm: Algorithm, key: [UInt8]) { self.algorithm = algorithm - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) CCHmacInit(context, algorithm.nativeValue(), key, size_t(key.count)) #elseif os(Linux) HMAC_Init_wrapper(context, key, Int32(key.count), .make(optional: algorithm.nativeValue())) @@ -274,7 +274,7 @@ public class HMAC: Updatable { public init(using algorithm: Algorithm, key: String) { self.algorithm = algorithm - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) CCHmacInit(context, algorithm.nativeValue(), key, size_t(key.lengthOfBytes(using: String.Encoding.utf8))) #elseif os(Linux) HMAC_Init_wrapper(context, key, Int32(key.utf8.count), .make(optional: algorithm.nativeValue())) @@ -307,7 +307,7 @@ public class HMAC: Updatable { /// public func update(from buffer: UnsafeRawPointer, byteCount: size_t) -> Self? { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) CCHmacUpdate(context, buffer, byteCount) #elseif os(Linux) HMAC_Update(context, buffer.assumingMemoryBound(to: UInt8.self), byteCount) @@ -323,7 +323,7 @@ public class HMAC: Updatable { public func final() -> [UInt8] { var hmac = Array(repeating: 0, count:algorithm.digestLength()) - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) CCHmacFinal(context, &hmac) #elseif os(Linux) var length: UInt32 = 0 diff --git a/Sources/Cryptor/KeyDerivation.swift b/Sources/Cryptor/KeyDerivation.swift index 7fa04d5..60d2354 100755 --- a/Sources/Cryptor/KeyDerivation.swift +++ b/Sources/Cryptor/KeyDerivation.swift @@ -17,7 +17,7 @@ import Foundation -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL @@ -46,7 +46,7 @@ public class PBKDF { /// Secure Hash Algorithm 2 512-bit case sha512 - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) /// Return the OS native value func nativeValue() -> CCPseudoRandomAlgorithm { @@ -103,7 +103,7 @@ public class PBKDF { /// public class func calibrate(passwordLength: Int, saltLength: Int, algorithm: PseudoRandomAlgorithm, derivedKeyLength: Int, msec: UInt32) -> UInt { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) return UInt(CCCalibratePBKDF(CCPBKDFAlgorithm(kCCPBKDF2), passwordLength, saltLength, algorithm.nativeValue(), derivedKeyLength, msec)) #elseif os(Linux) // Value as per RFC 2898. @@ -127,7 +127,7 @@ public class PBKDF { public class func deriveKey(fromPassword password: String, salt: String, prf: PseudoRandomAlgorithm, rounds: uint, derivedKeyLength: UInt) throws -> [UInt8] { var derivedKey = Array(repeating: 0, count:Int(derivedKeyLength)) - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) let status: Int32 = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, password.utf8.count, salt, salt.utf8.count, prf.nativeValue(), rounds, &derivedKey, derivedKey.count) if status != Int32(kCCSuccess) { @@ -159,7 +159,7 @@ public class PBKDF { public class func deriveKey(fromPassword password: String, salt: [UInt8], prf: PseudoRandomAlgorithm, rounds: uint, derivedKeyLength: UInt) throws -> [UInt8] { var derivedKey = Array(repeating: 0, count:Int(derivedKeyLength)) - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) let status: Int32 = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, password.utf8.count, salt, salt.count, prf.nativeValue(), rounds, &derivedKey, derivedKey.count) if status != Int32(kCCSuccess) { @@ -193,7 +193,7 @@ public class PBKDF { /// public class func deriveKey(fromPassword password: UnsafePointer, passwordLen: Int, salt: UnsafePointer, saltLen: Int, prf: PseudoRandomAlgorithm, rounds: uint, derivedKey: UnsafeMutablePointer, derivedKeyLen: Int) throws { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) let status: Int32 = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, passwordLen, salt, saltLen, prf.nativeValue(), rounds, derivedKey, derivedKeyLen) if status != Int32(kCCSuccess) { diff --git a/Sources/Cryptor/Random.swift b/Sources/Cryptor/Random.swift index 33266c6..dc61be4 100755 --- a/Sources/Cryptor/Random.swift +++ b/Sources/Cryptor/Random.swift @@ -17,7 +17,7 @@ import Foundation -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL @@ -41,7 +41,7 @@ public class Random { /// public class func generate(bytes: UnsafeMutablePointer, byteCount: Int) -> RNGStatus { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) let statusCode = CCRandomGenerateBytes(bytes, byteCount) guard let status = Status(rawValue: statusCode) else { fatalError("CCRandomGenerateBytes returned unexpected status code: \(statusCode)") diff --git a/Sources/Cryptor/Status.swift b/Sources/Cryptor/Status.swift index be87926..5691aec 100755 --- a/Sources/Cryptor/Status.swift +++ b/Sources/Cryptor/Status.swift @@ -17,13 +17,13 @@ import Foundation -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL #endif -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) /// /// Links the native CommonCryptoStatus enumeration to Swift versions. /// diff --git a/Sources/Cryptor/StreamCryptor.swift b/Sources/Cryptor/StreamCryptor.swift index b9cbcb0..da88ea6 100755 --- a/Sources/Cryptor/StreamCryptor.swift +++ b/Sources/Cryptor/StreamCryptor.swift @@ -17,7 +17,7 @@ import Foundation -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL @@ -74,8 +74,8 @@ public class StreamCryptor { /// Decrypting case decrypt - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + /// Convert to native `CCOperation` func nativeValue() -> CCOperation { @@ -185,10 +185,10 @@ public class StreamCryptor { } /// No options - public static let none = Options(rawValue: 0) - - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + public static let none = Options([]) + #if canImport(CommonCrypto) + /// Use padding. Needed unless the input is a integral number of blocks long. public static var pkcs7Padding = Options(rawValue:kCCOptionPKCS7Padding) @@ -285,8 +285,8 @@ public class StreamCryptor { } } - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + /// Native, CommonCrypto constant for algorithm. func nativeValue() -> CCAlgorithm { @@ -389,8 +389,8 @@ public class StreamCryptor { /// func validKeySize() -> ValidKeySize { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + switch self { case .aes, .aes128, .aes192, .aes256: @@ -478,8 +478,8 @@ public class StreamCryptor { /// private var haveContext: Bool = false - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + /// CommonCrypto Context private var context = UnsafeMutablePointer.allocate(capacity: 1) @@ -522,8 +522,8 @@ public class StreamCryptor { throw CryptorError.invalidIVSizeOrLength } - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + let rawStatus = CCCryptorCreate(operation.nativeValue(), algorithm.nativeValue(), CCOptions(options.rawValue), keyBuffer, keyByteCount, ivBuffer, self.context) if let status = Status.fromRaw(status: rawStatus) { @@ -644,8 +644,8 @@ public class StreamCryptor { return } - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + // Ensure we've got a context before attempting to get rid of it... if self.context.pointee == nil { return @@ -798,7 +798,7 @@ public class StreamCryptor { if self.status == .success { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) let rawStatus = CCCryptorUpdate(self.context.pointee, bufferIn, byteCountIn, bufferOut, byteCapacityOut, &byteCountOut) if let status = Status.fromRaw(status: rawStatus) { @@ -864,8 +864,8 @@ public class StreamCryptor { if self.status == Status.success { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + let rawStatus = CCCryptorFinal(self.context.pointee, bufferOut, byteCapacityOut, &byteCountOut) if let status = Status.fromRaw(status: rawStatus) { self.status = status @@ -921,7 +921,7 @@ public class StreamCryptor { /// public func getOutputLength(inputByteCount: Int, isFinal: Bool = false) -> Int { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) return CCCryptorGetOutputLength(self.context.pointee, inputByteCount, isFinal) diff --git a/Sources/Cryptor/Updatable.swift b/Sources/Cryptor/Updatable.swift index 5f98ab7..3355830 100755 --- a/Sources/Cryptor/Updatable.swift +++ b/Sources/Cryptor/Updatable.swift @@ -65,7 +65,7 @@ extension Updatable { public func update(data: Data) -> Self? { #if swift(>=5.0) - _ = data.withUnsafeBytes() { + data.withUnsafeBytes() { _ = update(from: $0.baseAddress!, byteCount: size_t(data.count)) } diff --git a/Sources/Cryptor/Utilities.swift b/Sources/Cryptor/Utilities.swift index 835c934..9be797f 100755 --- a/Sources/Cryptor/Utilities.swift +++ b/Sources/Cryptor/Utilities.swift @@ -206,7 +206,7 @@ public struct CryptoUtils { public static func hexNSString(from byteArray: [UInt8], uppercase: Bool = false) -> NSString { let formatString = (uppercase) ? "%02X" : "%02x" - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) return byteArray.map() { String(format: formatString, $0) }.reduce("", +) as NSString #else let aString = byteArray.map() { String(format: formatString, $0) }.reduce("", +) diff --git a/Tests/CryptorTests/CryptorTests.swift b/Tests/CryptorTests/CryptorTests.swift index f63743d..da2288b 100644 --- a/Tests/CryptorTests/CryptorTests.swift +++ b/Tests/CryptorTests/CryptorTests.swift @@ -19,7 +19,7 @@ import XCTest import Foundation @testable import Cryptor -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if canImport(CommonCrypto) import CommonCrypto #elseif os(Linux) import OpenSSL @@ -216,7 +216,7 @@ class CryptorTests: XCTestCase { let cryptor = try Cryptor(operation:.encrypt, algorithm:.aes, options:.ecbMode, key:key, iv:Array()) let cipherText = cryptor.update(byteArray: plainText)?.final() XCTAssert(cipherText == nil, "Expected nil cipherText") - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + #if canImport(CommonCrypto) XCTAssertEqual(cryptor.status, Status.alignmentError, "Expected AlignmentError") #endif } catch let error { @@ -761,8 +761,8 @@ class CryptorTests: XCTestCase { // MARK: - Status func test_Status() { - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - + #if canImport(CommonCrypto) + // These are only for CommonCrypto... XCTAssertEqual(Status.success.toRaw(), CCCryptorStatus(kCCSuccess)) XCTAssertEqual(Status.paramError.toRaw(), CCCryptorStatus(kCCParamError))