Skip to content

Commit ea7f8fb

Browse files
authored
Update to RC SDK (#410)
This patch brings us up-to-date with the RC SDK. There are a couple of tweaks to the MLDSA code and the XWing code, mostly a few minor interface changes. I've adopted those in the backing code, and also wired up the SHA3 integrity checks.
1 parent 890595d commit ea7f8fb

File tree

15 files changed

+345
-317
lines changed

15 files changed

+345
-317
lines changed

Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,26 @@ extension MLKEM768.InternalPrivateKey: BoringSSLBackedMLKEMPrivateKey {
102102
}
103103

104104
init<Bytes>(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws where Bytes: DataProtocol {
105-
precondition(publicKeyRawRepresentation == nil)
106-
self = try .init(seedRepresentation: seedRepresentation)
105+
let publicKeyHash = publicKeyRawRepresentation.map {
106+
SHA3_256.hash(data: $0)
107+
}
108+
self = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash)
107109
}
108110

109111
init<Bytes: DataProtocol>(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws {
110-
precondition(publicKeyHash == nil)
111112
self = try .init(seedRepresentation: seedRepresentation)
113+
let generatedHash = SHA3_256.hash(data: self.publicKey.rawRepresentation)
114+
if let publicKeyHash, generatedHash != publicKeyHash {
115+
throw KEM.Errors.publicKeyMismatchDuringInitialization
116+
}
112117
}
113118

114119
var integrityCheckedRepresentation: Data {
115-
fatalError()
120+
var representation = self.seedRepresentation
121+
SHA3_256.hash(data: self.publicKey.rawRepresentation).withUnsafeBytes {
122+
representation.append(contentsOf: $0)
123+
}
124+
return representation
116125
}
117126

118127
var interiorPublicKey: MLKEM768.InternalPublicKey {
@@ -155,17 +164,26 @@ extension MLKEM1024.InternalPrivateKey: BoringSSLBackedMLKEMPrivateKey {
155164
}
156165

157166
init<Bytes>(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws where Bytes: DataProtocol {
158-
precondition(publicKeyRawRepresentation == nil)
159-
self = try .init(seedRepresentation: seedRepresentation)
167+
let publicKeyHash = publicKeyRawRepresentation.map {
168+
SHA3_256.hash(data: $0)
169+
}
170+
self = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash)
160171
}
161172

162173
init<Bytes: DataProtocol>(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws {
163-
precondition(publicKeyHash == nil)
164174
self = try .init(seedRepresentation: seedRepresentation)
175+
let generatedHash = SHA3_256.hash(data: self.publicKey.rawRepresentation)
176+
if let publicKeyHash, generatedHash != publicKeyHash {
177+
throw KEM.Errors.publicKeyMismatchDuringInitialization
178+
}
165179
}
166180

167181
var integrityCheckedRepresentation: Data {
168-
fatalError()
182+
var representation = self.seedRepresentation
183+
SHA3_256.hash(data: self.publicKey.rawRepresentation).withUnsafeBytes {
184+
representation.append(contentsOf: $0)
185+
}
186+
return representation
169187
}
170188

171189
var interiorPublicKey: MLKEM1024.InternalPublicKey {

Sources/Crypto/KEM/BoringSSL/XWing_boring.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ struct OpenSSLXWingPublicKeyImpl: Sendable {
3030
self.publicKeyBytes = publicKeyBytes
3131
}
3232

33-
init<D: ContiguousBytes>(dataRepresentation: D) throws {
34-
self.publicKeyBytes = try dataRepresentation.withUnsafeBytes {
33+
init<D: ContiguousBytes>(rawRepresentation: D) throws {
34+
self.publicKeyBytes = try rawRepresentation.withUnsafeBytes {
3535
guard $0.count == XWING_PUBLIC_KEY_BYTES else {
3636
throw CryptoKitError.incorrectKeySize
3737
}
@@ -164,7 +164,7 @@ extension OpenSSLXWingPrivateKeyImpl {
164164
}
165165

166166
// Matching CryptoKit, we only care that this _is_ a public key, not that it matches.
167-
let _ = try OpenSSLXWingPublicKeyImpl(dataRepresentation: publicKeyBytes)
167+
let _ = try OpenSSLXWingPublicKeyImpl(rawRepresentation: publicKeyBytes)
168168
}
169169
}
170170

@@ -187,6 +187,10 @@ extension OpenSSLXWingPrivateKeyImpl {
187187
throw CryptoKitError.internalBoringSSLError()
188188
}
189189
}
190+
191+
if let publicKeyHash, publicKeyHash != self.publicKeyDigest {
192+
throw KEM.Errors.publicKeyMismatchDuringInitialization
193+
}
190194
}
191195

192196
var seedRepresentation: Data {
@@ -200,7 +204,11 @@ extension OpenSSLXWingPrivateKeyImpl {
200204
}
201205

202206
var integrityCheckedRepresentation: Data {
203-
fatalError()
207+
var representation = self.seedRepresentation
208+
self.publicKeyDigest.withUnsafeBytes {
209+
representation.append(contentsOf: $0)
210+
}
211+
return representation
204212
}
205213

206214
var dataRepresentation: Data {
@@ -215,6 +223,14 @@ extension OpenSSLXWingPrivateKeyImpl {
215223
}
216224
}
217225

226+
private var publicKeyDigest: SHA3_256Digest {
227+
withUnsafeTemporaryAllocation(byteCount: Int(XWING_PUBLIC_KEY_BYTES), alignment: 1) {
228+
let rc = CCryptoBoringSSL_XWING_public_from_private($0.baseAddress, &self.privateKey)
229+
precondition(rc == 1)
230+
return SHA3_256.hash(bufferPointer: UnsafeRawBufferPointer($0))
231+
}
232+
}
233+
218234
static func generate() throws -> Self {
219235
try Self()
220236
}

Sources/Crypto/KEM/XWing.swift

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,12 @@
1414
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
1515
@_exported import CryptoKit
1616
#else
17-
#if canImport(FoundationEssentials)
18-
public import FoundationEssentials
19-
#else
20-
public import Foundation
21-
#endif
22-
23-
#if _runtime(_ObjC) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
24-
@_exported import CryptoKit
25-
#else
2617

27-
#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
28-
import SwiftSystem
29-
#else
3018
#if canImport(FoundationEssentials)
3119
import FoundationEssentials
3220
#else
3321
import Foundation
3422
#endif
35-
#endif
3623

3724
#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
3825
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
@@ -61,8 +48,8 @@ extension XWingMLKEM768X25519 {
6148
self.impl = impl
6249
}
6350

64-
public init<D: ContiguousBytes>(dataRepresentation: D) throws {
65-
self.impl = try .init(dataRepresentation: dataRepresentation)
51+
public init<D: ContiguousBytes>(rawRepresentation: D) throws {
52+
self.impl = try .init(rawRepresentation: rawRepresentation)
6653
}
6754

6855
public var rawRepresentation: Data {
@@ -96,20 +83,10 @@ extension XWingMLKEM768X25519 {
9683
self.impl = impl
9784
}
9885

99-
public init<D: ContiguousBytes>(bytes: D) throws {
100-
self.impl = try .init(bytes: bytes)
101-
}
102-
10386
internal init<D: DataProtocol>(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws {
10487
self.impl = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash)
10588
}
10689

107-
public var dataRepresentation: Data {
108-
get {
109-
self.impl.dataRepresentation
110-
}
111-
}
112-
11390
public static func generate() throws -> XWingMLKEM768X25519.PrivateKey {
11491
return try Self(impl: XWingPrivateKeyImpl.generate())
11592
}
@@ -133,17 +110,12 @@ extension XWingMLKEM768X25519.PrivateKey: HPKEKEMPrivateKeyGeneration {
133110
}
134111

135112
public init<D: DataProtocol>(seedRepresentation: D, publicKey: XWingMLKEM768X25519.PublicKey?) throws {
136-
#if false
137113
var publicKeyHash: SHA3_256Digest? = nil
138114
if publicKey != nil {
139115
publicKeyHash = SHA3_256.hash(data: publicKey!.rawRepresentation)
140116
}
141117

142118
self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash)
143-
#else
144-
precondition(publicKey == nil)
145-
self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seedRepresentation, publicKeyHash: nil)
146-
#endif
147119
}
148120

149121
public init<D: DataProtocol>(integrityCheckedRepresentation: D) throws {
@@ -178,7 +150,7 @@ extension XWingMLKEM768X25519.PublicKey: HPKEKEMPublicKey {
178150
/// - Throws: ``CryptoKit/HPKE/Errors/inconsistentCiphersuiteAndKey`` if the key encapsulation mechanism requested is incompatible with this public key.
179151
public init<D>(_ serialization: D, kem: HPKE.KEM) throws where D: ContiguousBytes {
180152
try Self.validateCiphersuite(kem)
181-
try self.init(dataRepresentation: serialization)
153+
try self.init(rawRepresentation: serialization)
182154
}
183155

184156
/// Creates a serialized representation of the public key.
@@ -197,5 +169,4 @@ extension XWingMLKEM768X25519.PublicKey: HPKEKEMPublicKey {
197169
/// The type of the ephemeral private key associated with this public key.
198170
public typealias HPKEEphemeralPrivateKey = XWingMLKEM768X25519.PrivateKey
199171
}
200-
#endif
201172
#endif // Linux or !SwiftPM

Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ extension MLDSA87 {
639639

640640
enum MLDSA {
641641
/// The size of the seed in bytes.
642-
fileprivate static let seedByteCount = 32
642+
static let seedByteCount = 32
643643
}
644644

645645
#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API

Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ extension MLDSA${parameter_set} {
342342

343343
enum MLDSA {
344344
/// The size of the seed in bytes.
345-
fileprivate static let seedByteCount = 32
345+
static let seedByteCount = 32
346346
}
347347

348348
#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API

Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,29 @@ extension MLDSA87.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {}
8484
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
8585
struct OpenSSLMLDSAPrivateKeyImpl<Parameters: BoringSSLBackedMLDSAParameters> {
8686
private var backing: Parameters.BackingPrivateKey
87+
private let publicKeyHash: SHA3_256Digest
8788

8889
init() throws {
8990
self.backing = try .init()
91+
self.publicKeyHash = SHA3_256.hash(data: self.backing.publicKey.rawRepresentation)
9092
}
9193

92-
init<D: DataProtocol>(seedRepresentation: D, publicKey: OpenSSLMLDSAPublicKeyImpl<Parameters>?) throws {
93-
precondition(publicKey == nil)
94-
self.backing = try .init(seedRepresentation: seedRepresentation)
94+
init<D: DataProtocol>(seedRepresentation: D, publicKeyRawRepresentation: Data?) throws {
95+
let publicKeyHash = publicKeyRawRepresentation.map {
96+
SHA3_256.hash(data: $0)
97+
}
98+
self = try Self(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash)
9599
}
96100

97-
init<D: DataProtocol>(integrityCheckedRepresentation: D) throws {
98-
fatalError()
101+
init<D: DataProtocol>(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws {
102+
self.backing = try .init(seedRepresentation: seedRepresentation)
103+
let generatedHash = SHA3_256.hash(data: self.backing.publicKey.rawRepresentation)
104+
105+
if let publicKeyHash, generatedHash != publicKeyHash {
106+
throw CryptoKitError.unwrapFailure
107+
}
108+
109+
self.publicKeyHash = generatedHash
99110
}
100111

101112
func signature<D: DataProtocol>(for data: D) throws -> Data {
@@ -115,7 +126,16 @@ struct OpenSSLMLDSAPrivateKeyImpl<Parameters: BoringSSLBackedMLDSAParameters> {
115126
}
116127

117128
var integrityCheckedRepresentation: Data {
118-
fatalError()
129+
var representation = self.seedRepresentation
130+
representation.reserveCapacity(SHA3_256Digest.byteCount)
131+
self.publicKeyHash.withUnsafeBytes {
132+
representation.append(contentsOf: $0)
133+
}
134+
return representation
135+
}
136+
137+
static var seedSize: Int {
138+
MLDSA.seedByteCount
119139
}
120140
}
121141

@@ -132,14 +152,14 @@ struct OpenSSLMLDSAPublicKeyImpl<Parameters: BoringSSLBackedMLDSAParameters> {
132152
}
133153

134154
func isValidSignature<S: DataProtocol, D: DataProtocol>(
135-
signature: S,
155+
_ signature: S,
136156
for data: D
137157
) -> Bool {
138158
self.backing.isValidSignature(signature, for: data)
139159
}
140160

141161
func isValidSignature<S: DataProtocol, D: DataProtocol, C: DataProtocol>(
142-
signature: S,
162+
_ signature: S,
143163
for data: D,
144164
context: C
145165
) -> Bool {

0 commit comments

Comments
 (0)