Add unit tests for SHA3 signature verification

This commit is contained in:
Katrin Annuk
2023-11-13 18:37:18 +02:00
parent ada999a6e8
commit 5175133f53
4 changed files with 154 additions and 5 deletions
+5 -1
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -14,6 +14,7 @@
1467460F2017BB3600DF04ED /* AEAD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1467460E2017BB3600DF04ED /* AEAD.swift */; };
35F3E51C23BF9A6700A024A1 /* OCB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F3E51B23BF9A6700A024A1 /* OCB.swift */; };
42012783267A6F1C00F82506 /* ISO10126Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42012782267A6F1C00F82506 /* ISO10126Padding.swift */; };
5431FD5B2B021476001DEE77 /* SignatureVerificationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5431FD592B021470001DEE77 /* SignatureVerificationTests.swift */; };
674A736F1BF5D85B00866C5B /* RabbitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 674A736E1BF5D85B00866C5B /* RabbitTests.swift */; };
6A7CDEED26CD1E4C00FFB1AF /* RSATests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A7CDEEC26CD1E4C00FFB1AF /* RSATests.swift */; };
6AC893F626DB950F00F7E787 /* Addition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AC893E026DB950C00F7E787 /* Addition.swift */; };
@@ -240,6 +241,7 @@
35F3E51B23BF9A6700A024A1 /* OCB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OCB.swift; sourceTree = "<group>"; };
35F3E51D23BF9AD300A024A1 /* AESOCBTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AESOCBTests.swift; sourceTree = "<group>"; };
42012782267A6F1C00F82506 /* ISO10126Padding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ISO10126Padding.swift; sourceTree = "<group>"; };
5431FD592B021470001DEE77 /* SignatureVerificationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignatureVerificationTests.swift; sourceTree = "<group>"; };
674A736E1BF5D85B00866C5B /* RabbitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RabbitTests.swift; sourceTree = "<group>"; };
6A7CDEEC26CD1E4C00FFB1AF /* RSATests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSATests.swift; sourceTree = "<group>"; };
6AC893E026DB950C00F7E787 /* Addition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Addition.swift; sourceTree = "<group>"; };
@@ -581,6 +583,7 @@
75482EA31CB310B7001F66A5 /* PBKDF.swift */,
7576F6F6207290F8006688F8 /* PBKDFPerf.swift */,
6A7CDEEC26CD1E4C00FFB1AF /* RSATests.swift */,
5431FD592B021470001DEE77 /* SignatureVerificationTests.swift */,
75C2E76C1D55F097003D2BCA /* Access.swift */,
756BFDCA1A82B87300B9D9A4 /* Bridging.h */,
);
@@ -1106,6 +1109,7 @@
757DA2531A4ED0A4002BA3EF /* PaddingTests.swift in Sources */,
14156CE52011422400DDCFBC /* ChaCha20Poly1305Tests.swift in Sources */,
757DA2551A4ED408002BA3EF /* AESTests.swift in Sources */,
5431FD5B2B021476001DEE77 /* SignatureVerificationTests.swift in Sources */,
7594CCBC217A76DC0055C95D /* AESCCMTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
+19 -4
View File
@@ -121,6 +121,12 @@ extension RSA {
case message_pkcs1v15_SHA512_224
/// Hashes the raw message using SHA512-256 before signing the data
case message_pkcs1v15_SHA512_256
/// Hashes the raw message using SHA3_256 before signing the data
case message_pkcs1v15_SHA3_256
/// Hashes the raw message using SHA3_384 before signing the data
case message_pkcs1v15_SHA3_384
/// Hashes the raw message using SHA3_512 before signing the data
case message_pkcs1v15_SHA3_512
/// This variant isn't supported yet
case digest_pkcs1v15_RAW
/// This variant expects that the data to be signed is a valid MD5 Hash Digest
@@ -157,9 +163,9 @@ extension RSA {
case .message_pkcs1v15_SHA224, .digest_pkcs1v15_SHA224: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04)
case .message_pkcs1v15_SHA512_224, .digest_pkcs1v15_SHA512_224: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05)
case .message_pkcs1v15_SHA512_256, .digest_pkcs1v15_SHA512_256: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06)
case .digest_pkcs1v15_SHA3_256: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08)
case .digest_pkcs1v15_SHA3_384: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09)
case .digest_pkcs1v15_SHA3_512: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A)
case .message_pkcs1v15_SHA3_256, .digest_pkcs1v15_SHA3_256: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08)
case .message_pkcs1v15_SHA3_384, .digest_pkcs1v15_SHA3_384: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09)
case .message_pkcs1v15_SHA3_512, .digest_pkcs1v15_SHA3_512: return Array<UInt8>(arrayLiteral: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A)
}
}
@@ -181,6 +187,12 @@ extension RSA {
return Digest.sha2(bytes, variant: .sha224)
case .message_pkcs1v15_SHA512_256:
return Digest.sha2(bytes, variant: .sha256)
case .message_pkcs1v15_SHA3_256:
return Digest.sha3(bytes, variant: .sha256)
case .message_pkcs1v15_SHA3_384:
return Digest.sha3(bytes, variant: .sha384)
case .message_pkcs1v15_SHA3_512:
return Digest.sha3(bytes, variant: .sha512)
case .raw,
.digest_pkcs1v15_RAW,
.digest_pkcs1v15_MD5,
@@ -225,7 +237,10 @@ extension RSA {
.message_pkcs1v15_SHA384,
.message_pkcs1v15_SHA512,
.message_pkcs1v15_SHA512_224,
.message_pkcs1v15_SHA512_256:
.message_pkcs1v15_SHA512_256,
.message_pkcs1v15_SHA3_256,
.message_pkcs1v15_SHA3_384,
.message_pkcs1v15_SHA3_512:
return true
}
}
+6
View File
@@ -341,6 +341,9 @@ final class RSATests: XCTestCase {
XCTAssertThrowsError(try rsa.sign(message, variant: .digest_pkcs1v15_SHA512))
XCTAssertThrowsError(try rsa.sign(message, variant: .digest_pkcs1v15_SHA512_224))
XCTAssertThrowsError(try rsa.sign(message, variant: .digest_pkcs1v15_SHA512_256))
XCTAssertThrowsError(try rsa.sign(message, variant: .digest_pkcs1v15_SHA3_256))
XCTAssertThrowsError(try rsa.sign(message, variant: .digest_pkcs1v15_SHA3_384))
XCTAssertThrowsError(try rsa.sign(message, variant: .digest_pkcs1v15_SHA3_512))
// But if we hash the message first, then the signature works as expected...
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA1))
@@ -350,6 +353,9 @@ final class RSATests: XCTestCase {
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA512))
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA512_224))
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA512_256))
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA3_256))
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA3_384))
XCTAssertNoThrow(try rsa.sign(message, variant: .message_pkcs1v15_SHA3_512))
}
/// This test uses the Fixtures (generated using Apple's `Security` framework) to test the entirety of an RSA keys functionality
@@ -0,0 +1,124 @@
//// CryptoSwift
//
// Copyright (C) 2014-2023 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
// This software is provided 'as-is', without any express or implied warranty.
//
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
//
// - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
// - This notice may not be removed or altered from any source or binary distribution.
//
import Foundation
import XCTest
@testable import CryptoSwift
final class SignatureVerificationTests: XCTestCase {
func testVerifySHA3Variants() {
let testVectors: [SignatureVerificationTests.TestVector] = [
SignatureVerificationTests.testVectorMessage_pkcs1v15_SHA3_256,
SignatureVerificationTests.testVectorMessage_pkcs1v15_SHA3_384,
SignatureVerificationTests.testVectorMessage_pkcs1v15_SHA3_512,
SignatureVerificationTests.testVectorDigest_pkcs1v15_SHA3_256,
SignatureVerificationTests.testVectorDigest_pkcs1v15_SHA3_384,
SignatureVerificationTests.testVectorDigest_pkcs1v15_SHA3_512
]
for testVector in testVectors {
do {
guard
let publicDerData = Data(base64Encoded: testVector.publicDER)
else {
XCTFail("Corrupted data - publicDER")
continue
}
let rsa = try RSA(publicDER: publicDerData.bytes)
guard
let signedMessageData = Data(base64Encoded: testVector.signedMessage)
else {
XCTFail("Corrupted data - signedMessage")
continue
}
let result = try rsa.verify(signature: signedMessageData.bytes,
for: testVector.originalMessage.bytes,
variant: testVector.variant)
XCTAssertTrue(result, "Verification failed for test vector with id `\(testVector.id)`")
} catch let error {
XCTFail("Failed with error \(error)")
}
}
}
}
extension SignatureVerificationTests {
struct TestVector {
/// String to identify test vector. Used for logging purposes
let id: String
/// Public DER for RSA key
let publicDER: String
/// RSA signature variant
let variant: RSA.SignatureVariant
/// Original message that was signed
let originalMessage: String
/// Signed message
let signedMessage: String
}
static let testVectorMessage_pkcs1v15_SHA3_256 = TestVector(
id: "1",
publicDER: "MIGJAoGBAJPTOQB0cqHPbrZO8Bnl77uFR8jgcYWmudETdRP57lCn/Q4v4Ga9OTqTkfbzX7DKq4WrrcPkx6/u4U4EVS6y7jyuq3Qn4VZMQPKiMiqRyRKhNKfC0i8SpMEhnIXGl824bi/YfV6arz0gicl24dP8C+HsO+WJGa7gtRs2d8hY2s+NAgMBAAE=",
variant: .message_pkcs1v15_SHA3_256,
originalMessage: "CryptoSwift Test",
signedMessage: "IOIA/8NgoLVwtfto5Lnea7GLBXMddCAgQFBt38HVJpbEtuEcmu8uFs4sJuAHalH1iIe/cGPrwASRM94fSDKzuQ7XNX2Dwt8DBzu9BlAtEWq9GUSL/6DED0xJfqrl6G5rh+RRk9YYIk3TeI9H4HzsmIDFjp5hxFu0SedoR5DzEVM="
)
static let testVectorMessage_pkcs1v15_SHA3_384 = TestVector(
id: "2",
publicDER: "MIGJAoGBAJPTOQB0cqHPbrZO8Bnl77uFR8jgcYWmudETdRP57lCn/Q4v4Ga9OTqTkfbzX7DKq4WrrcPkx6/u4U4EVS6y7jyuq3Qn4VZMQPKiMiqRyRKhNKfC0i8SpMEhnIXGl824bi/YfV6arz0gicl24dP8C+HsO+WJGa7gtRs2d8hY2s+NAgMBAAE=",
variant: .message_pkcs1v15_SHA3_384,
originalMessage: "CryptoSwift Test",
signedMessage: "J1qAdFj7iwlW6Mhyf5MfG2CN7BeUjKCFeCunBs2Hginwpcz/YfJgzNpGA93T+RBR4kLVuhs3OVILhwaMnTbgsMVNz0xLoZ5oegRADXDT1Ln3WuTUuqQH+RiMSILelgaHsU4fjj7jCC8wLFA2DtYm7aje1HF3ZRc/9SQSTREM5Gw="
)
static let testVectorMessage_pkcs1v15_SHA3_512 = TestVector(
id: "3",
publicDER: "MIGJAoGBAJPTOQB0cqHPbrZO8Bnl77uFR8jgcYWmudETdRP57lCn/Q4v4Ga9OTqTkfbzX7DKq4WrrcPkx6/u4U4EVS6y7jyuq3Qn4VZMQPKiMiqRyRKhNKfC0i8SpMEhnIXGl824bi/YfV6arz0gicl24dP8C+HsO+WJGa7gtRs2d8hY2s+NAgMBAAE=",
variant: .message_pkcs1v15_SHA3_512,
originalMessage: "CryptoSwift Test",
signedMessage: "KMmRIptAPCZV7I/6gRN6wUQekRm+sxXWtoAyxC7PPiSBNd9XJTVVrEUnEfpnupI6uum+r9YxAT5Ha0S5XrYlojHZFLW3gZHLAKmRBushg8YRfqK68cDLYBshuqBlf5nuQZDU+7LTBh6Jnup2rGbQj1Bra9X9Hl9uZmoPY8Uoh/g="
)
static let testVectorDigest_pkcs1v15_SHA3_256 = TestVector(
id: "4",
publicDER: "MIGJAoGBAJPTOQB0cqHPbrZO8Bnl77uFR8jgcYWmudETdRP57lCn/Q4v4Ga9OTqTkfbzX7DKq4WrrcPkx6/u4U4EVS6y7jyuq3Qn4VZMQPKiMiqRyRKhNKfC0i8SpMEhnIXGl824bi/YfV6arz0gicl24dP8C+HsO+WJGa7gtRs2d8hY2s+NAgMBAAE=",
variant: .digest_pkcs1v15_SHA3_256,
originalMessage: "CryptoSwift Test",
signedMessage: "Oj3CBwMQIEGrQwFuqIXklqOJG6pdaS5Kjal+sAKoMvEzXCB0h8K8w9YNt/XIOD9fJXdUaG0XR6RB8eEQxh/u6pYZPVUwssyA//FUjWLgKOecNkaca+EK98iIkivjVdEGK7yVhcQHJF19EfpZahVWWlEUCT02g8niomkWUHWIlo8="
)
static let testVectorDigest_pkcs1v15_SHA3_384 = TestVector(
id: "5",
publicDER: "MIGJAoGBAJPTOQB0cqHPbrZO8Bnl77uFR8jgcYWmudETdRP57lCn/Q4v4Ga9OTqTkfbzX7DKq4WrrcPkx6/u4U4EVS6y7jyuq3Qn4VZMQPKiMiqRyRKhNKfC0i8SpMEhnIXGl824bi/YfV6arz0gicl24dP8C+HsO+WJGa7gtRs2d8hY2s+NAgMBAAE=",
variant: .digest_pkcs1v15_SHA3_384,
originalMessage: "CryptoSwift Test",
signedMessage: "ZCn19KmnT/QdzcNm077uopZeIxkR5EECX0po2QypPTYorYa9dGTm3nKR0mMr/G2C7ukrR2a8j5WPf4hXi1rlzOoFNufpbyQB33I9INleN7FjASmoxFcw6TyFNeMPN+TwKj9MVTEkZ7HtPL0bBsD8E08eRCDwk3UYdUjcvZcOdzw="
)
static let testVectorDigest_pkcs1v15_SHA3_512 = TestVector(
id: "6",
publicDER: "MIGJAoGBAJPTOQB0cqHPbrZO8Bnl77uFR8jgcYWmudETdRP57lCn/Q4v4Ga9OTqTkfbzX7DKq4WrrcPkx6/u4U4EVS6y7jyuq3Qn4VZMQPKiMiqRyRKhNKfC0i8SpMEhnIXGl824bi/YfV6arz0gicl24dP8C+HsO+WJGa7gtRs2d8hY2s+NAgMBAAE=",
variant: .digest_pkcs1v15_SHA3_512,
originalMessage: "CryptoSwift Test",
signedMessage: "bk1/rtzt64ZApavxPrUEnsG/tN7nN6ITV3NKY0IR1i/3S4bkxIMulRsBPINpksTAafxrSm6EsLAmOPrqjwGycqRjSRi8/S6roUE/TIno2dGfO5e4eVKCQtD6I+CHA0Xji3X1k627vaYZqpTMFuMk8serfjMTHFe46s6S+f/64as="
)
}