Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,14 @@ let package = Package(
name: "CryptoTests",
dependencies: ["Crypto"],
resources: [
.copy("HPKE/hpke-test-vectors.json")
.copy("HPKE/hpke-test-vectors.json"),
.copy("KEM/MLKEM768_BSSLKAT.json"),
.copy("KEM/MLKEM768KAT.json"),
.copy("KEM/MLKEM1024_BSSLKAT.json"),
.copy("KEM/MLKEM1024KAT.json"),
.copy("KEM/test-vectors.json"),
.copy("Signatures/MLDSA/MLDSA65_KeyGen_KAT.json"),
.copy("Signatures/MLDSA/MLDSA87_KeyGen_KAT.json"),
],
swiftSettings: swiftSettings
),
Expand Down
2 changes: 2 additions & 0 deletions Sources/CCryptoBoringSSL/include/CCryptoBoringSSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "CCryptoBoringSSL_cmac.h"
#include "CCryptoBoringSSL_conf.h"
#include "CCryptoBoringSSL_cpu.h"
#include "CCryptoBoringSSL_ctrdrbg.h"
#include "CCryptoBoringSSL_curve25519.h"
#include "CCryptoBoringSSL_des.h"
#include "CCryptoBoringSSL_e_os2.h"
Expand Down Expand Up @@ -62,5 +63,6 @@
#include "CCryptoBoringSSL_siphash.h"
#include "CCryptoBoringSSL_trust_token.h"
#include "CCryptoBoringSSL_x509v3.h"
#include "CCryptoBoringSSL_xwing.h"

#endif // C_CRYPTO_BORINGSSL_H
35 changes: 21 additions & 14 deletions Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
@_exported import CryptoKit
#else
#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
typealias AESGCMImpl = CoreCryptoGCMImpl
import Security
#else
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
typealias AESGCMImpl = OpenSSLAESGCMImpl
#endif

import Foundation
#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
public import SwiftSystem
#else
public import Foundation
#endif

@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
extension AES {
/// The Advanced Encryption Standard (AES) Galois Counter Mode (GCM) cipher
/// suite.
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
public enum GCM: Cipher {
public enum GCM: Cipher, Sendable {
static let tagByteCount = 16
static let defaultNonceByteCount = 12

Expand All @@ -41,12 +44,12 @@ extension AES {
/// - Parameters:
/// - message: The plaintext data to seal.
/// - key: A cryptographic key used to seal the message.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES.GCM.Nonce()``.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES/GCM/Nonce/init()``.
/// - authenticatedData: Additional data to be authenticated.
///
/// - Returns: The sealed message.
public static func seal<Plaintext: DataProtocol, AuthenticatedData: DataProtocol>
(_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil, authenticating authenticatedData: AuthenticatedData) throws -> SealedBox {
(_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil, authenticating authenticatedData: AuthenticatedData) throws(CryptoKitMetaError) -> SealedBox {
return try AESGCMImpl.seal(key: key, message: message, nonce: nonce, authenticatedData: authenticatedData)
}

Expand All @@ -56,11 +59,11 @@ extension AES {
/// - Parameters:
/// - message: The plaintext data to seal.
/// - key: A cryptographic key used to seal the message.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES.GCM.Nonce()``.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES/GCM/Nonce/init()``.
///
/// - Returns: The sealed message.
public static func seal<Plaintext: DataProtocol>
(_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil) throws -> SealedBox {
(_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil) throws(CryptoKitMetaError) -> SealedBox {
return try AESGCMImpl.seal(key: key, message: message, nonce: nonce, authenticatedData: Data?.none)
}

Expand All @@ -76,7 +79,7 @@ extension AES {
/// box, as long as the correct key is used and authentication succeeds.
/// The call throws an error if decryption or authentication fail.
public static func open<AuthenticatedData: DataProtocol>
(_ sealedBox: SealedBox, using key: SymmetricKey, authenticating authenticatedData: AuthenticatedData) throws -> Data {
(_ sealedBox: SealedBox, using key: SymmetricKey, authenticating authenticatedData: AuthenticatedData) throws(CryptoKitMetaError) -> Data {
return try AESGCMImpl.open(key: key, sealedBox: sealedBox, authenticatedData: authenticatedData)
}

Expand All @@ -89,7 +92,7 @@ extension AES {
/// - Returns: The original plaintext message that was sealed in the
/// box, as long as the correct key is used and authentication succeeds.
/// The call throws an error if decryption or authentication fail.
public static func open(_ sealedBox: SealedBox, using key: SymmetricKey) throws -> Data {
public static func open(_ sealedBox: SealedBox, using key: SymmetricKey) throws(CryptoKitMetaError) -> Data {
return try AESGCMImpl.open(key: key, sealedBox: sealedBox, authenticatedData: Data?.none)
}
}
Expand All @@ -112,7 +115,7 @@ extension AES.GCM {
/// The receiver uses another instance of the same cipher, like the
/// ``open(_:using:)`` method, to open the box.
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
public struct SealedBox: AEADSealedBox {
public struct SealedBox: AEADSealedBox, Sendable {
private let combinedRepresentation: Data
private let nonceByteCount: Int

Expand Down Expand Up @@ -167,13 +170,17 @@ extension AES.GCM {
/// - combined: The combined bytes of the nonce, encrypted data, and
/// authentication tag.
@inlinable
public init<D: DataProtocol>(combined: D) throws {
public init<D: DataProtocol>(combined: D) throws(CryptoKitMetaError) {
// AES minimum nonce (12 bytes) + AES tag (16 bytes)
// While we have these values in the internal APIs, we can't use it in inlinable code.
let aesGCMOverhead = 12 + 16

if combined.count < aesGCMOverhead {
#if hasFeature(Embedded)
throw CryptoKitMetaError.cryptoKitError(underlyingError: CryptoKitError.incorrectParameterSize)
#else
throw CryptoKitError.incorrectParameterSize
#endif
}

self.init(combined: Data(combined))
Expand All @@ -185,9 +192,9 @@ extension AES.GCM {
/// - nonce: The nonce.
/// - ciphertext: The encrypted data.
/// - tag: The authentication tag.
public init<C: DataProtocol, T: DataProtocol>(nonce: AES.GCM.Nonce, ciphertext: C, tag: T) throws {
public init<C: DataProtocol, T: DataProtocol>(nonce: AES.GCM.Nonce, ciphertext: C, tag: T) throws(CryptoKitMetaError) {
guard tag.count == AES.GCM.tagByteCount else {
throw CryptoKitError.incorrectParameterSize
throw error(CryptoKitError.incorrectParameterSize)
}

let nonceByteCount = nonce.bytes.count
Expand Down
18 changes: 11 additions & 7 deletions Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
@_exported import CryptoKit
#else
#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
typealias ChaChaPolyImpl = CoreCryptoChaChaPolyImpl
import Security
#else
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
typealias ChaChaPolyImpl = OpenSSLChaChaPolyImpl
#endif

import Foundation
#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
public import SwiftSystem
#else
public import Foundation
#endif


/// An implementation of the ChaCha20-Poly1305 cipher.
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
public enum ChaChaPoly: Cipher {
public enum ChaChaPoly: Cipher, Sendable {
static let tagByteCount = 16
static let keyBitsCount = 256
static let nonceByteCount = 12
Expand All @@ -39,7 +43,7 @@ public enum ChaChaPoly: Cipher {
/// - Parameters:
/// - message: The plaintext data to seal.
/// - key: A cryptographic key used to seal the message.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly.Nonce()``.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly/Nonce/init()``.
/// - authenticatedData: Additional data to be authenticated.
///
/// - Returns: The sealed message.
Expand All @@ -54,7 +58,7 @@ public enum ChaChaPoly: Cipher {
/// - Parameters:
/// - message: The plaintext data to seal.
/// - key: A cryptographic key used to seal the message.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly.Nonce()``.
/// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly/Nonce/init()``.
///
/// - Returns: The sealed message.
public static func seal<Plaintext: DataProtocol>
Expand Down Expand Up @@ -111,7 +115,7 @@ extension ChaChaPoly {
/// ``open(_:using:)`` method, to open the box.
@frozen
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
public struct SealedBox: AEADSealedBox {
public struct SealedBox: AEADSealedBox, Sendable {
/// A combined element composed of the tag, the nonce, and the
/// ciphertext.
///
Expand Down
12 changes: 9 additions & 3 deletions Sources/Crypto/AEADs/Cipher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
@_exported import CryptoKit
#else

#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
import SwiftSystem
#else
import Foundation
#endif


@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
protocol AEADSealedBox {
protocol AEADSealedBox: Sendable {
associatedtype Nonce: Sequence
/// The authentication tag
var tag: Data { get }
Expand Down Expand Up @@ -52,7 +58,7 @@ protocol Cipher {
/// - Returns: The sealed box containing the ciphertext and authentication tag
/// - Throws: An error occurred while encrypting or authenticating.
static func seal<Plaintext: DataProtocol, AuthenticatedData: DataProtocol>
(_ message: Plaintext, using key: SymmetricKey, nonce: Nonce?, authenticating: AuthenticatedData) throws -> SealedBox
(_ message: Plaintext, using key: SymmetricKey, nonce: Nonce?, authenticating: AuthenticatedData) throws(CryptoKitMetaError) -> SealedBox

/// Opens the sealed box. This decrypts and verifies the authenticity of the message,
/// and optionally verifies the authenticity of the authenticated data.
Expand All @@ -65,6 +71,6 @@ protocol Cipher {
/// - Returns: Returns the data, if the correct key is used and the authenticated data matches the one from the seal operation.
/// - Throws: An error occurred while decrypting or authenticating.
static func open<AuthenticatedData: DataProtocol>
(_ sealedBox: SealedBox, using key: Key, authenticating: AuthenticatedData) throws -> Data
(_ sealedBox: SealedBox, using key: Key, authenticating: AuthenticatedData) throws(CryptoKitMetaError) -> Data
}
#endif
45 changes: 32 additions & 13 deletions Sources/Crypto/AEADs/Nonces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
@_exported import CryptoKit
#else
import Foundation
#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION
public import SwiftSystem
#else
public import Foundation
#endif
// MARK: - Generated file, do NOT edit
// any edits of this file WILL be overwritten and thus discarded
// see section `gyb` in `README` for details.




// MARK: - AES.GCM + Nonce
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
extension AES.GCM {
Expand All @@ -28,7 +35,7 @@ extension AES.GCM {
/// that nonces are unique per call to encryption APIs in order to protect the
/// integrity of the encryption.
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
public struct Nonce: ContiguousBytes, Sequence {
public struct Nonce: ContiguousBytes, Sequence, Sendable {
let bytes: Data

/// Creates a new random nonce.
Expand All @@ -49,11 +56,11 @@ extension AES.GCM {
/// ``init()`` method to instead create a random nonce.
///
/// - Parameters:
/// - data: A 12-byte data representation of the nonce. The initializer throws an
/// error if the data has a length other than 12 bytes.
public init<D: DataProtocol>(data: D) throws {
/// - data: A data representation of the nonce.
/// The initializer throws an error if the data has a length smaller than 12 bytes.
public init<D: DataProtocol>(data: D) throws(CryptoKitMetaError) {
if data.count < AES.GCM.defaultNonceByteCount {
throw CryptoKitError.incorrectParameterSize
throw error(CryptoKitError.incorrectParameterSize)
}

self.bytes = Data(data)
Expand All @@ -70,10 +77,16 @@ extension AES.GCM {
/// the duration of the closure’s execution.
///
/// - Returns: The return value, if any, of the body closure parameter.
#if !hasFeature(Embedded)
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try self.bytes.withUnsafeBytes(body)
}

#else
public func withUnsafeBytes<R, E: Error>(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R {
return try self.bytes.withUnsafeBytes(body)
}
#endif

/// Returns an iterator over the elements of the nonce.
public func makeIterator() -> Array<UInt8>.Iterator {
self.withUnsafeBytes({ (buffPtr) in
Expand All @@ -92,7 +105,7 @@ extension ChaChaPoly {
/// that nonces are unique per call to encryption APIs in order to protect the
/// integrity of the encryption.
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
public struct Nonce: ContiguousBytes, Sequence {
public struct Nonce: ContiguousBytes, Sequence, Sendable {
let bytes: Data

/// Creates a new random nonce.
Expand All @@ -113,11 +126,11 @@ extension ChaChaPoly {
/// ``init()`` method to instead create a random nonce.
///
/// - Parameters:
/// - data: A 12-byte data representation of the nonce. The initializer throws an
/// error if the data has a length other than 12 bytes.
public init<D: DataProtocol>(data: D) throws {
/// - data: A 12-byte data representation of the nonce.
/// The initializer throws an error if the data isn't 12 bytes long.
public init<D: DataProtocol>(data: D) throws(CryptoKitMetaError) {
if data.count != ChaChaPoly.nonceByteCount {
throw CryptoKitError.incorrectParameterSize
throw error(CryptoKitError.incorrectParameterSize)
}

self.bytes = Data(data)
Expand All @@ -134,10 +147,16 @@ extension ChaChaPoly {
/// the duration of the closure’s execution.
///
/// - Returns: The return value, if any, of the body closure parameter.
#if !hasFeature(Embedded)
public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
return try self.bytes.withUnsafeBytes(body)
}

#else
public func withUnsafeBytes<R, E: Error>(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R {
return try self.bytes.withUnsafeBytes(body)
}
#endif

/// Returns an iterator over the elements of the nonce.
public func makeIterator() -> Array<UInt8>.Iterator {
self.withUnsafeBytes({ (buffPtr) in
Expand Down
Loading
Loading