From f673c481c7013244694ba458712b73721a57bd20 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Mon, 16 Jun 2025 18:03:10 +0100 Subject: [PATCH 1/7] Adopt Swift 6 mode Motivation The Swift 6 language mode adopts data-race safety by default. While Swift Crypto itself has no concurrent code, it is still useful to force us to ensure that our code is properly Sendable-correct. Modifications - @unchecked Sendable on several CoW data types - Some necessary Sendable constraints on ECToolbox protocols - Add some missing protocol constraints on ARC types. Result Swift 6 clean. --- Package.swift | 2 +- Sources/Crypto/Digests/BoringSSL/Digest_boring.swift | 2 +- Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift | 8 ++++---- Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb | 11 ++--------- Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift | 10 +++++----- .../Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift | 4 ++-- .../Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift | 12 ++++++------ .../Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift | 4 ++-- .../Crypto/Signatures/BoringSSL/MLDSA_boring.swift | 8 ++++---- .../Signatures/BoringSSL/MLDSA_boring.swift.gyb | 4 ++-- .../Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift | 4 ++-- Sources/CryptoBoringWrapper/EC/EllipticCurve.swift | 2 +- .../Util/FiniteFieldArithmeticContext.swift | 6 +++--- Sources/_CryptoExtras/ARC/ARCPrecredential.swift | 2 +- Sources/_CryptoExtras/ARC/ARCServer.swift | 2 +- Sources/_CryptoExtras/ECToolbox/ECToolbox.swift | 4 ++-- Sources/_CryptoExtras/RSA/RSA_boring.swift | 4 ++-- Sources/_CryptoExtras/Util/DigestType.swift | 8 ++++---- 18 files changed, 45 insertions(+), 52 deletions(-) diff --git a/Package.swift b/Package.swift index 4f177f4ac..992a6f452 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version:6.0 //===----------------------------------------------------------------------===// // // This source file is part of the SwiftCrypto open source project diff --git a/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift b/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift index b6e759cf2..479190155 100644 --- a/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift +++ b/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift @@ -144,7 +144,7 @@ extension SHA512: BoringSSLBackedHashFunction { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLDigestImpl { +struct OpenSSLDigestImpl: @unchecked Sendable { private var context: DigestContext init() { diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift index ae7690c33..77b6d6cbe 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift @@ -29,7 +29,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// A ML-KEM-768 private key. - struct InternalPrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: @unchecked Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-768 private key from a random seed. @@ -175,7 +175,7 @@ extension MLKEM768 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// A ML-KEM-768 public key. - struct InternalPublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: @unchecked Sendable, KEMPublicKey { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -296,7 +296,7 @@ extension MLKEM768 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// A ML-KEM-1024 private key. - struct InternalPrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: @unchecked Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-1024 private key from a random seed. @@ -442,7 +442,7 @@ extension MLKEM1024 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// A ML-KEM-1024 public key. - struct InternalPublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: @unchecked Sendable, KEMPublicKey { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb index 979cf314b..112376e5d 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb @@ -33,7 +33,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// A ML-KEM-${parameter_set} private key. - struct InternalPrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: @unchecked Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-${parameter_set} private key from a random seed. @@ -179,7 +179,7 @@ extension MLKEM${parameter_set} { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// A ML-KEM-${parameter_set} public key. - struct InternalPublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: @unchecked Sendable, KEMPublicKey { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -207,13 +207,6 @@ extension MLKEM${parameter_set} { self.backing.encapsulate() } - /// Encapsulate a shared secret using a fixed RNG result. - /// - /// - Returns: The shared secret and its encapsulated version. - func encapsulateWithSeed(_ encapWithSeed: Data) -> KEM.EncapsulationResult { - self.backing.encapsulate(encapWithSeed) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift index 9fc83b433..dbebc87ab 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift @@ -23,7 +23,7 @@ import Foundation #endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLKEMPrivateKey { +protocol BoringSSLBackedMLKEMPrivateKey: Sendable { associatedtype InteriorPublicKey: BoringSSLBackedMLKEMPublicKey static func generatePrivateKey() throws -> Self @@ -51,7 +51,7 @@ extension BoringSSLBackedMLKEMPrivateKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLKEMPublicKey { +protocol BoringSSLBackedMLKEMPublicKey: Sendable { init(rawRepresentation: Bytes) throws var rawRepresentation: Data { get } @@ -62,7 +62,7 @@ protocol BoringSSLBackedMLKEMPublicKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLKEMOuterPublicKey { +protocol BoringSSLBackedMLKEMOuterPublicKey: Sendable { init(rawRepresentation: Data) throws } @@ -181,7 +181,7 @@ extension MLKEM1024.InternalPublicKey: BoringSSLBackedMLKEMPublicKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLMLKEMPublicKeyImpl: BoringSSLBackedMLKEMPublicKey { +struct OpenSSLMLKEMPublicKeyImpl: BoringSSLBackedMLKEMPublicKey, Sendable { private var backing: Parameters.BackingPublicKey init(backing: Parameters.BackingPublicKey) { @@ -206,7 +206,7 @@ struct OpenSSLMLKEMPublicKeyImpl: Bo } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey { +struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey, Sendable { typealias InteriorPublicKey = OpenSSLMLKEMPublicKeyImpl private var backing: Parameters.BackingPrivateKey diff --git a/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift index 4ed7ea723..037de26f6 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift @@ -27,7 +27,7 @@ import Foundation extension Curve25519.Signing { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PrivateKeyImpl { + struct OpenSSLCurve25519PrivateKeyImpl: Sendable { var _privateKey: SecureBytes @usableFromInline var _publicKey: [UInt8] @@ -99,7 +99,7 @@ extension Curve25519.Signing { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PublicKeyImpl { + struct OpenSSLCurve25519PublicKeyImpl: Sendable { @usableFromInline var keyBytes: [UInt8] diff --git a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift index 11441322e..ce159e391 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift @@ -64,7 +64,7 @@ extension P521: OpenSSLSupportedNISTCurve { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLNISTCurvePrivateKeyImpl { +struct OpenSSLNISTCurvePrivateKeyImpl: Sendable { @usableFromInline var key: BoringSSLECPrivateKeyWrapper @@ -95,7 +95,7 @@ struct OpenSSLNISTCurvePrivateKeyImpl { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLNISTCurvePublicKeyImpl { +struct OpenSSLNISTCurvePublicKeyImpl: Sendable { @usableFromInline var key: BoringSSLECPublicKeyWrapper @@ -145,9 +145,9 @@ struct OpenSSLNISTCurvePublicKeyImpl { /// allows some helper operations. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -class BoringSSLECPrivateKeyWrapper { +class BoringSSLECPrivateKeyWrapper: @unchecked Sendable { @usableFromInline - var key: OpaquePointer + let key: OpaquePointer init(compactRepresentable: Bool) throws { // We cannot handle allocation failure. @@ -350,9 +350,9 @@ class BoringSSLECPrivateKeyWrapper { /// allows some helper operations. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -class BoringSSLECPublicKeyWrapper { +class BoringSSLECPublicKeyWrapper: @unchecked Sendable { @usableFromInline - var key: OpaquePointer + let key: OpaquePointer init(compactRepresentation bytes: Bytes) throws { let group = Curve.group diff --git a/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift index b51db37de..df7807cdc 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift @@ -29,7 +29,7 @@ extension Curve25519.KeyAgreement { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PublicKeyImpl { + struct OpenSSLCurve25519PublicKeyImpl: Sendable { @usableFromInline var keyBytes: [UInt8] @@ -57,7 +57,7 @@ extension Curve25519.KeyAgreement { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PrivateKeyImpl { + struct OpenSSLCurve25519PrivateKeyImpl: Sendable { var key: SecureBytes @usableFromInline diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index c058e71cc..bfba93044 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -36,7 +36,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// A ML-DSA-65 private key. - struct InternalPrivateKey: Sendable { + struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-65 private key from a random seed. @@ -193,7 +193,7 @@ extension MLDSA65 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// A ML-DSA-65 public key. - struct InternalPublicKey: Sendable { + struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -338,7 +338,7 @@ extension MLDSA65 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// A ML-DSA-87 private key. - struct InternalPrivateKey: Sendable { + struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-87 private key from a random seed. @@ -495,7 +495,7 @@ extension MLDSA87 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// A ML-DSA-87 public key. - struct InternalPublicKey: Sendable { + struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index c9d42191b..ee0b1f0c8 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -40,7 +40,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set} { /// A ML-DSA-${parameter_set} private key. - struct InternalPrivateKey: Sendable { + struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-${parameter_set} private key from a random seed. @@ -197,7 +197,7 @@ extension MLDSA${parameter_set} { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set} { /// A ML-DSA-${parameter_set} public key. - struct InternalPublicKey: Sendable { + struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index c8171c6b4..671847b3e 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -23,7 +23,7 @@ import Foundation #endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLDSAPrivateKey { +protocol BoringSSLBackedMLDSAPrivateKey: Sendable { associatedtype AssociatedPublicKey: BoringSSLBackedMLDSAPublicKey init() throws @@ -40,7 +40,7 @@ protocol BoringSSLBackedMLDSAPrivateKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLDSAPublicKey { +protocol BoringSSLBackedMLDSAPublicKey: Sendable { init(rawRepresentation: D) throws func isValidSignature(_: S, for data: D) -> Bool diff --git a/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift b/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift index 7358ddb86..c333ecbd2 100644 --- a/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift +++ b/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift @@ -17,7 +17,7 @@ /// liveness. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -package final class BoringSSLEllipticCurveGroup { +package final class BoringSSLEllipticCurveGroup: @unchecked Sendable { @usableFromInline var _group: OpaquePointer @usableFromInline package let order: ArbitraryPrecisionInteger diff --git a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift index f5c6d435c..39e62b2d9 100644 --- a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift +++ b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift @@ -34,9 +34,9 @@ import Foundation /// ourselves. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -package class FiniteFieldArithmeticContext { - private var fieldSize: ArbitraryPrecisionInteger - package var bnCtx: OpaquePointer +package class FiniteFieldArithmeticContext: @unchecked Sendable { + private let fieldSize: ArbitraryPrecisionInteger + package let bnCtx: OpaquePointer @usableFromInline package init(fieldSize: ArbitraryPrecisionInteger) throws { diff --git a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift index 27c5c5ac7..b1281fa95 100644 --- a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift +++ b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift @@ -20,7 +20,7 @@ import Foundation @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { - struct ClientSecrets { + struct ClientSecrets { let m1: Scalar // secret at request and verification let m2: Scalar // secret at request, public at verification (server expected to know value) let r1: Scalar // secret blinding factor for m1 diff --git a/Sources/_CryptoExtras/ARC/ARCServer.swift b/Sources/_CryptoExtras/ARC/ARCServer.swift index 53f890046..8d4bef6b0 100644 --- a/Sources/_CryptoExtras/ARC/ARCServer.swift +++ b/Sources/_CryptoExtras/ARC/ARCServer.swift @@ -20,7 +20,7 @@ import Foundation @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { - struct ServerPrivateKey { + struct ServerPrivateKey { let x0: Scalar let x1: Scalar let x2: Scalar diff --git a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift b/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift index 452ed640f..a1eb80e90 100644 --- a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift +++ b/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift @@ -57,7 +57,7 @@ protocol HashToGroup { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol GroupScalar { +protocol GroupScalar: Sendable { init(bytes: Data, reductionIsModOrder: Bool) throws var rawRepresentation: Data { get } @@ -80,7 +80,7 @@ protocol GroupScalar { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol GroupElement { +protocol GroupElement: Sendable { associatedtype Scalar: GroupScalar static var generator: Self { get } diff --git a/Sources/_CryptoExtras/RSA/RSA_boring.swift b/Sources/_CryptoExtras/RSA/RSA_boring.swift index fae4da655..b35743f53 100644 --- a/Sources/_CryptoExtras/RSA/RSA_boring.swift +++ b/Sources/_CryptoExtras/RSA/RSA_boring.swift @@ -200,7 +200,7 @@ extension BoringSSLRSAPublicKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension BoringSSLRSAPublicKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - fileprivate final class Backing { + fileprivate final class Backing: @unchecked Sendable { private let pointer: OpaquePointer fileprivate init(takingOwnershipOf pointer: OpaquePointer) { @@ -571,7 +571,7 @@ extension BoringSSLRSAPublicKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension BoringSSLRSAPrivateKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - fileprivate final class Backing { + fileprivate final class Backing: @unchecked Sendable { private let pointer: OpaquePointer fileprivate init(copying other: Backing) { diff --git a/Sources/_CryptoExtras/Util/DigestType.swift b/Sources/_CryptoExtras/Util/DigestType.swift index e4d268a57..469c56873 100644 --- a/Sources/_CryptoExtras/Util/DigestType.swift +++ b/Sources/_CryptoExtras/Util/DigestType.swift @@ -17,12 +17,12 @@ import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct DigestType { - var dispatchTable: OpaquePointer +struct DigestType: @unchecked Sendable { + let dispatchTable: OpaquePointer - var nid: CInt + let nid: CInt - var digestLength: Int + let digestLength: Int /// The dispatchtable pointer must have static storage and not be lifetime managed, /// as it is assumed to last for the duration of the program. From 1734b36486f94aadd61df5ae96aa3f2b1251d16b Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 07:57:54 +0100 Subject: [PATCH 2/7] Formatting --- Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift index dbebc87ab..3306cedd6 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift @@ -206,7 +206,8 @@ struct OpenSSLMLKEMPublicKeyImpl: Bo } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey, Sendable { +struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey, Sendable +{ typealias InteriorPublicKey = OpenSSLMLKEMPublicKeyImpl private var backing: Parameters.BackingPrivateKey From 3a739a30ccb4ff808e9e73225021123c887006c2 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 08:12:44 +0100 Subject: [PATCH 3/7] Clean up excludes --- Package.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Package.swift b/Package.swift index 992a6f452..3d92c6858 100644 --- a/Package.swift +++ b/Package.swift @@ -142,6 +142,10 @@ let package = Package( "Digests/Digests.swift.gyb", "Key Agreement/ECDH.swift.gyb", "Signatures/ECDSA.swift.gyb", + "Signatures/MLDSA.swift.gyb", + "Signatures/BoringSSL/MLDSA_boring.swift.gyb", + "KEM/MLKEM.swift.gyb", + "KEM/BoringSSL/MLKEM_boring.swift.gyb", ], resources: privacyManifestResource, swiftSettings: swiftSettings From f0a848d4b1f3199a100fc117984bf66d4d1bde01 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 09:35:54 +0100 Subject: [PATCH 4/7] Replace #file with #filePath --- .../Authenticated Encryption/AES-GCM-Runner.swift | 2 +- .../Authenticated Encryption/ChaChaPoly-Runner.swift | 2 +- Tests/CryptoTests/Digests/DigestsTests.swift | 2 +- .../CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift | 6 +++--- Tests/CryptoTests/MAC/HMACTests.swift | 2 +- .../CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift | 2 +- .../Signatures/ECDSA/RawECDSASignaturesTests.swift | 4 ++-- Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift | 2 +- Tests/CryptoTests/Utils/RFCVector.swift | 2 +- Tests/CryptoTests/Utils/Wycheproof.swift | 4 ++-- Tests/CryptoTests/Utils/XCTestUtils.swift | 6 +++--- Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift | 2 +- Tests/_CryptoExtrasTests/MLDSATests.swift | 4 ++-- Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift | 2 +- Tests/_CryptoExtrasTests/TestRSABlindSigning.swift | 2 +- Tests/_CryptoExtrasTests/Utils/RFCVector.swift | 2 +- Tests/_CryptoExtrasTests/Utils/Wycheproof.swift | 4 ++-- Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift | 4 ++-- 18 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift index c51dd7dc4..6c0dcd145 100644 --- a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift @@ -156,7 +156,7 @@ class AESGCMTests: XCTestCase { } func testRoundTripDataProtocols() throws { - func roundTrip(message: Message, aad: AAD, file: StaticString = (#file), line: UInt = #line) throws { + func roundTrip(message: Message, aad: AAD, file: StaticString = (#filePath), line: UInt = #line) throws { let key = SymmetricKey(size: .bits256) let nonce = AES.GCM.Nonce() let ciphertext = try orFail(file: file, line: line) { try AES.GCM.seal(message, using: key, nonce: nonce, authenticating: aad) } diff --git a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift index a36f0b55d..c5967a717 100644 --- a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift @@ -122,7 +122,7 @@ class ChaChaPolyTests: XCTestCase { } func testRoundTripDataProtocols() throws { - func roundTrip(message: Message, aad: AAD, file: StaticString = (#file), line: UInt = #line) throws { + func roundTrip(message: Message, aad: AAD, file: StaticString = (#filePath), line: UInt = #line) throws { let key = SymmetricKey(size: .bits256) let nonce = ChaChaPoly.Nonce() diff --git a/Tests/CryptoTests/Digests/DigestsTests.swift b/Tests/CryptoTests/Digests/DigestsTests.swift index 1bd5c7c39..0fc345df8 100644 --- a/Tests/CryptoTests/Digests/DigestsTests.swift +++ b/Tests/CryptoTests/Digests/DigestsTests.swift @@ -78,7 +78,7 @@ func testVectorForAlgorithm(hashFunction: H.Type) throws -> Str } class DigestsTests: XCTestCase { - func assertHashFunctionWithVector(hf: H.Type, data: Data, testVector: String, file: StaticString = (#file), line: UInt = #line) throws { + func assertHashFunctionWithVector(hf: H.Type, data: Data, testVector: String, file: StaticString = (#filePath), line: UInt = #line) throws { var h = hf.init() h.update(data: data) let result = h.finalize() diff --git a/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift b/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift index 6503f7d5c..d1d82af06 100644 --- a/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift +++ b/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift @@ -37,7 +37,7 @@ extension NISTECDHTests { group: ECDHTestGroup, privateKeys: PrivKey.Type, onCurve curve: Curve.Type, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { for testVector in group.tests { @@ -89,7 +89,7 @@ extension NISTECDHTests { group: ECDHTestGroup, privateKeys: PrivKey.Type, onCurve curve: Curve.Type, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { for testVector in group.tests { @@ -126,7 +126,7 @@ extension NISTECDHTests { private func padKeyIfNecessary( curve: Curve.Type, vector: String, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) throws -> [UInt8] { // There are a few edge cases here. diff --git a/Tests/CryptoTests/MAC/HMACTests.swift b/Tests/CryptoTests/MAC/HMACTests.swift index 34f3e6bd1..df36bb117 100644 --- a/Tests/CryptoTests/MAC/HMACTests.swift +++ b/Tests/CryptoTests/MAC/HMACTests.swift @@ -105,7 +105,7 @@ class HMACTests: XCTestCase { } } - func testHMAC(key: SymmetricKey, data: Data, vectors: (H.Type) throws -> String, for: H.Type, file: StaticString = #file, line: UInt = #line) throws -> Bool { + func testHMAC(key: SymmetricKey, data: Data, vectors: (H.Type) throws -> String, for: H.Type, file: StaticString = #filePath, line: UInt = #line) throws -> Bool { let code = try orFail(file: file, line: line) { try Data(hexString: vectors(H.self)) } return HMAC.isValidAuthenticationCode(code, authenticating: data, using: key) } diff --git a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift index f3e2fcd2c..fc72e4c52 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift @@ -148,7 +148,7 @@ class SignatureTests: XCTestCase { } } - func testGroup(group: ECDSATestGroup, curve: C.Type, hashFunction: HF.Type, deserializeSignature: (Data) throws -> C.ECDSASignature, file: StaticString = #file, line: UInt = #line) throws where C.ECDSASignature == C.PublicKey.Signature { + func testGroup(group: ECDSATestGroup, curve: C.Type, hashFunction: HF.Type, deserializeSignature: (Data) throws -> C.ECDSASignature, file: StaticString = #filePath, line: UInt = #line) throws where C.ECDSASignature == C.PublicKey.Signature { let keyBytes = try orFail(file: file, line: line) { try Array(hexString: group.publicKey.uncompressed) } let key = try orFail(file: file, line: line) { try C.PublicKey(x963Representation: keyBytes) } diff --git a/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift b/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift index 5902d6f85..a085be4e2 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift @@ -25,7 +25,7 @@ import XCTest typealias TestVector = (publicKey: Data, privateKey: Data, rs: rAndS) typealias rAndS = (r: Data, s: Data) -func testVectorForCurve(curve: S.Type, file: StaticString = #file, line: UInt = #line) throws -> TestVector { +func testVectorForCurve(curve: S.Type, file: StaticString = #filePath, line: UInt = #line) throws -> TestVector { switch S.self { case is P256.Signing.Type: do { @@ -56,7 +56,7 @@ func testVectorForCurve(curve: S.Type, file: StaticString = #fil } class RawECDSASignaturesTests: XCTestCase { - func testForCurve(curve: S.Type, file: StaticString = #file, line: UInt = #line) throws { + func testForCurve(curve: S.Type, file: StaticString = #filePath, line: UInt = #line) throws { let msg = try unwrap("abc".data(using: .utf8), file: file, line: line) // We check that the test message is correctly encoded. XCTAssertEqual(msg, try Data(hexString: "616263"), file: file, line: line) diff --git a/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift b/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift index 326bf3d68..c025e04cb 100644 --- a/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift +++ b/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift @@ -105,7 +105,7 @@ class Ed25519Tests: XCTestCase { } } - func testGroup(group: Ed25519TestGroup, file: StaticString = #file, line: UInt = #line) throws { + func testGroup(group: Ed25519TestGroup, file: StaticString = #filePath, line: UInt = #line) throws { let keyBytes = try orFail { try Array(hexString: group.publicKey.pk) } let key = try orFail { try Curve25519.Signing.PublicKey(rawRepresentation: keyBytes) } diff --git a/Tests/CryptoTests/Utils/RFCVector.swift b/Tests/CryptoTests/Utils/RFCVector.swift index ea582b32a..363a083e1 100644 --- a/Tests/CryptoTests/Utils/RFCVector.swift +++ b/Tests/CryptoTests/Utils/RFCVector.swift @@ -29,7 +29,7 @@ struct RFCVectorDecoder { let bundle = Bundle(for: type(of: bundleType)) let fileURL = bundle.url(forResource: fileName, withExtension: "txt") #else - var fileURL: URL? = URL(fileURLWithPath: "\(#file)") + var fileURL: URL? = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL!.deleteLastPathComponent() } diff --git a/Tests/CryptoTests/Utils/Wycheproof.swift b/Tests/CryptoTests/Utils/Wycheproof.swift index a40fe0439..fc381339d 100644 --- a/Tests/CryptoTests/Utils/Wycheproof.swift +++ b/Tests/CryptoTests/Utils/Wycheproof.swift @@ -20,12 +20,12 @@ struct WycheproofTest: Codable { } extension XCTestCase { - func wycheproofTest(bundleType: AnyObject, jsonName: String, file: StaticString = #file, line: UInt = #line, testFunction: (T) throws -> Void) throws { + func wycheproofTest(bundleType: AnyObject, jsonName: String, file: StaticString = #filePath, line: UInt = #line, testFunction: (T) throws -> Void) throws { #if !CRYPTO_IN_SWIFTPM let bundle = Bundle(for: type(of: bundleType)) let fileURL = bundle.url(forResource: jsonName, withExtension: "json") #else - var fileURL = URL(fileURLWithPath: "\(#file)") + var fileURL = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL.deleteLastPathComponent() } diff --git a/Tests/CryptoTests/Utils/XCTestUtils.swift b/Tests/CryptoTests/Utils/XCTestUtils.swift index 819d290b7..87e8dbe6b 100644 --- a/Tests/CryptoTests/Utils/XCTestUtils.swift +++ b/Tests/CryptoTests/Utils/XCTestUtils.swift @@ -17,7 +17,7 @@ import Crypto // Xcode 11.4 catches errors thrown during tests and reports them on the // correct line. But Linux and older Xcodes do not, so we need to use this // wrapper as long as those platforms are supported. -func orFail(file: StaticString = #file, line: UInt = #line, _ closure: () throws -> T) throws -> T { +func orFail(file: StaticString = #filePath, line: UInt = #line, _ closure: () throws -> T) throws -> T { func wrapper(_ closure: () throws -> U, file: StaticString, line: UInt) throws -> U { do { return try closure() @@ -45,7 +45,7 @@ extension XCTestCase { /// been marked as `throws`. /// - Note: this is a replacement for `XCTUnwrap`, which is not available /// in SPM command line builds as of this writing: - func unwrap(_ optional: T?, file: StaticString = (#file), line: UInt = #line) throws -> T { + func unwrap(_ optional: T?, file: StaticString = (#filePath), line: UInt = #line) throws -> T { guard let wrapped = optional else { XCTFail("Optional was nil", file: file, line: line) throw OptionalUnwrappingError(file: file, line: line) @@ -59,7 +59,7 @@ func XCTAssertThrowsError( _ expression: @autoclosure () throws -> T, error: E, _ message: @autoclosure () -> String = "", - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line) { XCTAssertThrowsError(try expression(), message(), file: file, line: line) { foundError in diff --git a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift b/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift index 6cfa781f3..3d5ddea5b 100644 --- a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift +++ b/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift @@ -152,7 +152,7 @@ final class AESGCMSIVTests: XCTestCase { } func testRoundTripDataProtocols() throws { - func roundTrip(message: Message, aad: AAD, file: StaticString = (#file), line: UInt = #line) throws { + func roundTrip(message: Message, aad: AAD, file: StaticString = (#filePath), line: UInt = #line) throws { let key = SymmetricKey(size: .bits256) let nonce = AES.GCM._SIV.Nonce() let ciphertext = try AES.GCM._SIV.seal(message, using: key, nonce: nonce, authenticating: aad) diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 01ddbd743..42edd033d 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -224,11 +224,11 @@ final class MLDSATests: XCTestCase { @available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) private func nistTest( jsonName: String, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line, testFunction: (Vector) throws -> Void ) throws { - var fileURL = URL(fileURLWithPath: "\(#file)") + var fileURL = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<2 { fileURL.deleteLastPathComponent() } diff --git a/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift b/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift index 0a8323c94..cf4582c23 100644 --- a/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift +++ b/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift @@ -24,7 +24,7 @@ extension OPRFSuite { static let allValues: [Self] = try! OPRFSuite.load(from: URL( fileURLWithPath: "OPRFVectors/OPRFVectors-VOPRFDraft19.json", - relativeTo: URL(fileURLWithPath: #file) + relativeTo: URL(fileURLWithPath: #filePath) )) static var P384_SHA384_VORPF: Self { diff --git a/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift b/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift index fa42b2ee3..fb6a9c32e 100644 --- a/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift +++ b/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift @@ -43,7 +43,7 @@ struct RFC9474TestVector: Codable { static let allValues: [Self] = try! RFC9474TestVector.load(from: URL( fileURLWithPath: "../_CryptoExtrasVectors/rfc9474.json", - relativeTo: URL(fileURLWithPath: #file) + relativeTo: URL(fileURLWithPath: #filePath) )) } diff --git a/Tests/_CryptoExtrasTests/Utils/RFCVector.swift b/Tests/_CryptoExtrasTests/Utils/RFCVector.swift index c7d8df7e9..bc6748989 100644 --- a/Tests/_CryptoExtrasTests/Utils/RFCVector.swift +++ b/Tests/_CryptoExtrasTests/Utils/RFCVector.swift @@ -25,7 +25,7 @@ struct RFCVectorDecoder { private var index: Int? init(bundleType: AnyObject, fileName: String) throws { - var fileURL: URL? = URL(fileURLWithPath: "\(#file)") + var fileURL: URL? = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL!.deleteLastPathComponent() } diff --git a/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift b/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift index 42d9e8c95..9c7025617 100644 --- a/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift +++ b/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift @@ -20,8 +20,8 @@ struct WycheproofTest: Codable { } extension XCTestCase { - func wycheproofTest(jsonName: String, file: StaticString = #file, line: UInt = #line, testFunction: (T) throws -> Void) throws { - var fileURL = URL(fileURLWithPath: "\(#file)") + func wycheproofTest(jsonName: String, file: StaticString = #filePath, line: UInt = #line, testFunction: (T) throws -> Void) throws { + var fileURL = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL.deleteLastPathComponent() } diff --git a/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift b/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift index 9f0878e6f..1be6d3cd4 100644 --- a/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift +++ b/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift @@ -16,7 +16,7 @@ import XCTest // Xcode 11.4 catches errors thrown during tests and reports them on the // correct line. But Linux and older Xcodes do not, so we need to use this // wrapper as long as those platforms are supported. -func orFail(file: StaticString = #file, line: UInt = #line, _ closure: () throws -> T) throws -> T { +func orFail(file: StaticString = #filePath, line: UInt = #line, _ closure: () throws -> T) throws -> T { func wrapper(_ closure: () throws -> U, file: StaticString, line: UInt) throws -> U { do { return try closure() @@ -37,7 +37,7 @@ func XCTAssertThrowsError( _ expression: @autoclosure () throws -> T, error expectedError: E, _ message: @autoclosure () -> String = "", - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line) { XCTAssertThrowsError(try expression(), message(), file: file, line: line) { error in XCTAssertEqual(error as? E, expectedError, message(), file: file, line: line) From 3230d9082126601bdb977b62186b7631c5ee08a6 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 10:22:06 +0100 Subject: [PATCH 5/7] Remove redundant Equatable check as it no longer compiles --- .../AES-GCM-Runner.swift | 1 + .../ChaChaPoly-Runner.swift | 1 + .../ECprivateKeysFromSeeds.swift | 51 ------------------- 3 files changed, 2 insertions(+), 51 deletions(-) delete mode 100644 Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift diff --git a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift index 6c0dcd145..0a1890a76 100644 --- a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift @@ -44,6 +44,7 @@ struct AESGCMTestVector: Codable { let result: String } +@available(iOS 17.4, macOS 14.4, watchOS 10.4, tvOS 17.4, macCatalyst 17.4, *) class AESGCMTests: XCTestCase { func testPropertiesStayTheSameAfterFailedOpening() throws { let message = Data("this is a message".utf8) diff --git a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift index c5967a717..f0ccb430e 100644 --- a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift @@ -26,6 +26,7 @@ import CryptoKit import Crypto #endif +@available(iOS 17.4, macOS 14.4, watchOS 10.4, tvOS 17.4, macCatalyst 17.4, *) class ChaChaPolyTests: XCTestCase { func testIncorrectKeySize() throws { let plaintext: Data = "Some Super Secret Message".data(using: String.Encoding.utf8)! diff --git a/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift b/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift deleted file mode 100644 index ef4d0cef2..000000000 --- a/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift +++ /dev/null @@ -1,51 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif -import XCTest - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -// Skip tests that require @testable imports of CryptoKit. -#else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@testable import CryptoKit -#else -@testable import Crypto -#endif - -extension CryptoKitError: Equatable { - public static func == (lhs: CryptoKitError, rhs: CryptoKitError) -> Bool { - switch (lhs, rhs) { - case (.incorrectKeySize, .incorrectKeySize): - return true - case (.incorrectParameterSize, .incorrectParameterSize): - return true - case (.authenticationFailure, .authenticationFailure): - return true - case (.wrapFailure, .wrapFailure): - return true - case (.unwrapFailure, .unwrapFailure): - return true - case (.underlyingCoreCryptoError(let lhsError), .underlyingCoreCryptoError(let rhsError)): - return lhsError == rhsError - default: - return false - } - } -} - -#endif // Linux or !SwiftPM From 7b9323f43abbaabbd425bfc91bd2028105dd07b7 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 12:00:44 +0100 Subject: [PATCH 6/7] Handle MLKEM encapsulation key differences --- Tests/_CryptoExtrasTests/MLKEMTests.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Tests/_CryptoExtrasTests/MLKEMTests.swift b/Tests/_CryptoExtrasTests/MLKEMTests.swift index 007a88a5a..b9cdf95e3 100644 --- a/Tests/_CryptoExtrasTests/MLKEMTests.swift +++ b/Tests/_CryptoExtrasTests/MLKEMTests.swift @@ -37,8 +37,12 @@ final class MLKEMTests: XCTestCase { var modifiedPublicKeyBytes = publicKeyBytes modifiedPublicKeyBytes[0] = 0xff modifiedPublicKeyBytes[1] = 0xff - // Parsing should fail because the first coefficient is >= kPrime; - XCTAssertThrowsError(try MLKEM768.PublicKey(rawRepresentation: modifiedPublicKeyBytes)) + // Parsing should fail because the first coefficient is >= kPrime. The check may be delayed + // to the encapsulation stage. + XCTAssertThrowsError(try { + let pk = try MLKEM768.PublicKey(rawRepresentation: modifiedPublicKeyBytes) + _ = try pk.encapsulate() + }()) let publicKey2 = try MLKEM768.PublicKey(rawRepresentation: publicKeyBytes) XCTAssertEqual(publicKeyBytes, publicKey2.rawRepresentation) @@ -83,8 +87,12 @@ final class MLKEMTests: XCTestCase { var modifiedPublicKeyBytes = publicKeyBytes modifiedPublicKeyBytes[0] = 0xff modifiedPublicKeyBytes[1] = 0xff - // Parsing should fail because the first coefficient is >= kPrime; - XCTAssertThrowsError(try MLKEM1024.PublicKey(rawRepresentation: modifiedPublicKeyBytes)) + // Parsing should fail because the first coefficient is >= kPrime. The check may be delayed + // to the encapsulation stage. + XCTAssertThrowsError(try { + let pk = try MLKEM1024.PublicKey(rawRepresentation: modifiedPublicKeyBytes) + _ = try pk.encapsulate() + }()) let publicKey2 = try MLKEM1024.PublicKey(rawRepresentation: publicKeyBytes) XCTAssertEqual(publicKeyBytes, publicKey2.rawRepresentation) From d924484826fbfb634940bbdb04e3a53b08bb693a Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 12:20:38 +0100 Subject: [PATCH 7/7] Formatting --- Tests/_CryptoExtrasTests/MLKEMTests.swift | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Tests/_CryptoExtrasTests/MLKEMTests.swift b/Tests/_CryptoExtrasTests/MLKEMTests.swift index b9cdf95e3..ae6351ca3 100644 --- a/Tests/_CryptoExtrasTests/MLKEMTests.swift +++ b/Tests/_CryptoExtrasTests/MLKEMTests.swift @@ -39,10 +39,12 @@ final class MLKEMTests: XCTestCase { modifiedPublicKeyBytes[1] = 0xff // Parsing should fail because the first coefficient is >= kPrime. The check may be delayed // to the encapsulation stage. - XCTAssertThrowsError(try { - let pk = try MLKEM768.PublicKey(rawRepresentation: modifiedPublicKeyBytes) - _ = try pk.encapsulate() - }()) + XCTAssertThrowsError( + try { + let pk = try MLKEM768.PublicKey(rawRepresentation: modifiedPublicKeyBytes) + _ = try pk.encapsulate() + }() + ) let publicKey2 = try MLKEM768.PublicKey(rawRepresentation: publicKeyBytes) XCTAssertEqual(publicKeyBytes, publicKey2.rawRepresentation) @@ -89,10 +91,12 @@ final class MLKEMTests: XCTestCase { modifiedPublicKeyBytes[1] = 0xff // Parsing should fail because the first coefficient is >= kPrime. The check may be delayed // to the encapsulation stage. - XCTAssertThrowsError(try { - let pk = try MLKEM1024.PublicKey(rawRepresentation: modifiedPublicKeyBytes) - _ = try pk.encapsulate() - }()) + XCTAssertThrowsError( + try { + let pk = try MLKEM1024.PublicKey(rawRepresentation: modifiedPublicKeyBytes) + _ = try pk.encapsulate() + }() + ) let publicKey2 = try MLKEM1024.PublicKey(rawRepresentation: publicKeyBytes) XCTAssertEqual(publicKeyBytes, publicKey2.rawRepresentation)