From fa0ef8ff914de47748634f3ed3ea82069def110c Mon Sep 17 00:00:00 2001 From: Michele Balistreri Date: Fri, 30 Apr 2021 11:46:48 +0300 Subject: [PATCH] make 3DES keys 24 bytes long --- Sources/Keycard/Crypto.swift | 22 ++++++++++++++++++ Sources/Keycard/Keycard.swift | 4 ++-- Tests/KeycardTests/CryptoTests.swift | 24 ++++++++++++++++++-- Tests/KeycardTests/GlobalPlatformTests.swift | 22 ++++++++++++++++++ 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 Tests/KeycardTests/GlobalPlatformTests.swift diff --git a/Sources/Keycard/Crypto.swift b/Sources/Keycard/Crypto.swift index 71137b9..1ecd17c 100644 --- a/Sources/Keycard/Crypto.swift +++ b/Sources/Keycard/Crypto.swift @@ -46,6 +46,17 @@ class Crypto { CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(0), &tmpKey, key.count, &tmpIV, &tmpData, data.count, &out, out.count, &encrypted) return out } + + func desDec(data: [UInt8], iv: [UInt8], key: [UInt8]) -> [UInt8] { + var out: [UInt8] = [UInt8](repeating: 0, count: data.count) + var decrypted: Int = 0 + var tmpKey = key + var tmpData = data + var tmpIV = iv + + CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(0), &tmpKey, key.count, &tmpIV, &tmpData, data.count, &out, out.count, &decrypted) + return out + } func des3Enc(data: [UInt8], iv: [UInt8], key: [UInt8]) -> [UInt8] { var out: [UInt8] = [UInt8](repeating: 0, count: data.count) @@ -58,6 +69,17 @@ class Crypto { return out } + func des3Dec(data: [UInt8], iv: [UInt8], key: [UInt8]) -> [UInt8] { + var out: [UInt8] = [UInt8](repeating: 0, count: data.count) + var decrypted: Int = 0 + var tmpKey = key + var tmpData = data + var tmpIV = iv + + CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithm3DES), CCOptions(0), &tmpKey, key.count, &tmpIV, &tmpData, data.count, &out, out.count, &decrypted) + return out + } + func des3Mac(data: [UInt8], iv: [UInt8], key: [UInt8]) -> [UInt8] { let enc: [UInt8] = des3Enc(data: data, iv: iv, key: key) return Array(enc.suffix(8)) diff --git a/Sources/Keycard/Keycard.swift b/Sources/Keycard/Keycard.swift index b4b4699..3148413 100644 --- a/Sources/Keycard/Keycard.swift +++ b/Sources/Keycard/Keycard.swift @@ -127,8 +127,8 @@ public enum Identifier: String { } public enum GlobalPlatformKeys: String { - case defaultKeys = "404142434445464748494a4b4c4d4e4f" - case statusKeys = "c212e073ff8b4bbfaff4de8ab655221f" + case defaultKeys = "404142434445464748494a4b4c4d4e4f4041424344454647" + case statusKeys = "c212e073ff8b4bbfaff4de8ab655221fc212e073ff8b4bbf" public var val: [UInt8] { return rawValue.hexToBytes diff --git a/Tests/KeycardTests/CryptoTests.swift b/Tests/KeycardTests/CryptoTests.swift index a315722..a1febd9 100644 --- a/Tests/KeycardTests/CryptoTests.swift +++ b/Tests/KeycardTests/CryptoTests.swift @@ -2,8 +2,7 @@ import XCTest @testable import Keycard final class CryptoTests: XCTestCase { - - func test_encrypt_decrypt() { + func testAES() { let plaintext = "Hello, World!" let plaintextBytes = [UInt8](plaintext.utf8) @@ -17,4 +16,25 @@ final class CryptoTests: XCTestCase { XCTAssertEqual(decryptedText, plaintext) } + func testDES() { + let plaintext = "Hello, World!" + let paddedData = Crypto.shared.iso7816_4Pad(data: [UInt8](plaintext.utf8), blockSize: 8) + + let iv = Crypto.shared.random(count: 8) + let key = GlobalPlatformKeys.statusKeys.val + + let encrypted = Crypto.shared.desEnc(data: paddedData, iv: iv, key: Crypto.shared.resizeDESKey8(key)) + let decrypted = Crypto.shared.desDec(data: encrypted, iv: iv, key: Crypto.shared.resizeDESKey8(key)) + XCTAssertEqual(decrypted, paddedData) + + let encrypted3 = Crypto.shared.des3Enc(data: paddedData, iv: iv, key: key) + let decrypted3 = Crypto.shared.des3Dec(data: encrypted3, iv: iv, key: key) + XCTAssertEqual(decrypted3, paddedData) + + let mac = Crypto.shared.des3Mac(data: paddedData, iv: iv, key: key) + XCTAssertEqual(encrypted3.suffix(8), mac) + + let fullMac = Crypto.shared.des3FullMac(data: paddedData, iv: iv, key: key) + XCTAssertEqual(fullMac.count, 8) + } } diff --git a/Tests/KeycardTests/GlobalPlatformTests.swift b/Tests/KeycardTests/GlobalPlatformTests.swift new file mode 100644 index 0000000..49d4e60 --- /dev/null +++ b/Tests/KeycardTests/GlobalPlatformTests.swift @@ -0,0 +1,22 @@ +import XCTest +@testable import Keycard + +final class GlobalPlatformTests: XCTestCase { + func testSCP02() { + let scp02 = SCP02(channel: TestCardChannel()) + let hostChallenge = Crypto.shared.random(count: 8) + var cardChallenge = Crypto.shared.random(count: 8) + cardChallenge[0] = 0x00 + cardChallenge[1] = 0x0f + + var cardData = [UInt8](repeating: 0, count: 12) + cardData.append(contentsOf: cardChallenge) + + let encKey = scp02.deriveSessionKey(key: GlobalPlatformKeys.statusKeys.val, seq: [0x00, 0x0f], purpose: SCP02.derivationPurposeEnc) + scp02.encKey = encKey + cardData.append(contentsOf: scp02.generateCryptogram(challenge1: hostChallenge, challenge2: cardChallenge)) + + XCTAssertTrue(scp02.verifyChallenge(hostChallenge: hostChallenge, key: GlobalPlatformKeys.statusKeys.val, cardResponse: cardData)) + XCTAssertFalse(scp02.verifyChallenge(hostChallenge: hostChallenge, key: GlobalPlatformKeys.defaultKeys.val, cardResponse: cardData)) + } +}