From bce1725222a0547c061fb71eab460aff1aa1e28b Mon Sep 17 00:00:00 2001 From: michael-yuji Date: Mon, 16 Dec 2024 04:26:11 -0800 Subject: [PATCH 1/2] FreeBSD support (#315) Fix FreeBSD support ### Checklist - [x] I've run tests to see all new and existing tests pass - [x] I've followed the code style of the rest of the project - [x] I've read the [Contribution Guidelines](CONTRIBUTING.md) - [x] I've updated the documentation if necessary ### Motivation: To add FreeBSD support to Swift, we must ensure that swift crypto builds on FreeBSD since it's a dependency of swiftpm and several essential packages. ### Modifications: - `Package.swift` - Ideally FreeBSD should use `.when(platforms:)` to set the corresponding swift settings and dependencies. However, `Platform.freebsd` is not yet available on swiftpm and therefore use guard the settings behind a `isFreeBSD` boolean flag. This is chosen because it minimize the diff and maintains the maximum readability. - `cmake/modules/SwiftSupport.cmake` - add `amd64` arch support, maps to `x86_64`. - `**/CMakeLists.txt` - Use the Linux assembly files for FreeBSD. Both Linux and FreeBSD uses SysV ABI, and there're no syscalls involved (after all, they're supposed to be "pure") so there are no ABI compatibility problem. After all, all the tests are passing on FreeBSD with this PR. ### Result: All the tests (via `swift test`) passed on x86_64 FreeBSD 14.1-p6, and passed on aarch64 macOS. Test log available here: [swift-test-result.txt](https://github.com/user-attachments/files/18147920/swift-test-result.txt) --- Package.swift | 13 +++++++++++-- Sources/CCryptoBoringSSL/CMakeLists.txt | 4 ++-- Sources/Crypto/CMakeLists.txt | 2 +- Sources/CryptoBoringWrapper/Util/RandomBytes.swift | 2 +- Tests/CryptoTests/Encodings/DERTests.swift | 2 +- cmake/modules/SwiftSupport.cmake | 2 ++ 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Package.swift b/Package.swift index 04f0df2e..61d98e23 100644 --- a/Package.swift +++ b/Package.swift @@ -27,9 +27,18 @@ import PackageDescription // To develop this on Apple platforms, set this to true let development = false +// Ideally, we should use `.when(platforms:)` to set `swiftSettings` and +// `dependencies` like on other platforms. However, `Platform.freebsd` is not +// yet available, and therefore we guard the settings behind this boolean. +#if os(FreeBSD) +let isFreeBSD = true +#else +let isFreeBSD = false +#endif + let swiftSettings: [SwiftSetting] let dependencies: [Target.Dependency] -if development { +if development || isFreeBSD { swiftSettings = [ .define("CRYPTO_IN_SWIFTPM"), .define("CRYPTO_IN_SWIFTPM_FORCE_BUILD_API"), @@ -44,7 +53,7 @@ if development { Platform.linux, Platform.android, Platform.windows, - Platform.wasi, + Platform.wasi ] swiftSettings = [ .define("CRYPTO_IN_SWIFTPM"), diff --git a/Sources/CCryptoBoringSSL/CMakeLists.txt b/Sources/CCryptoBoringSSL/CMakeLists.txt index 5b11945c..84ac892f 100644 --- a/Sources/CCryptoBoringSSL/CMakeLists.txt +++ b/Sources/CCryptoBoringSSL/CMakeLists.txt @@ -276,7 +276,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL Darwin AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x gen/crypto/chacha-x86_64-apple.S gen/crypto/chacha20_poly1305_x86_64-apple.S gen/crypto/md5-x86_64-apple.S) -elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android" AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64") +elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD" AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64") target_sources(CCryptoBoringSSL PRIVATE gen/bcm/aes-gcm-avx10-x86_64-linux.S gen/bcm/aesni-gcm-x86_64-linux.S @@ -313,7 +313,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm gen/bcm/vpaes-armv8-apple.S gen/crypto/chacha-armv8-apple.S gen/crypto/chacha20_poly1305_armv8-apple.S) -elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") +elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") target_sources(CCryptoBoringSSL PRIVATE gen/bcm/aesv8-armv8-linux.S gen/bcm/aesv8-gcm-armv8-linux.S diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index 95a1c437..3bc8e1bb 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -96,7 +96,7 @@ add_library(Crypto target_compile_definitions(Crypto PRIVATE "$<$:CRYPTO_IN_SWIFTPM>") -if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "WASI") +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "WASI" OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD) target_compile_definitions(Crypto PRIVATE "$<$:CRYPTO_IN_SWIFTPM_FORCE_BUILD_API>") endif() diff --git a/Sources/CryptoBoringWrapper/Util/RandomBytes.swift b/Sources/CryptoBoringWrapper/Util/RandomBytes.swift index fc3970d0..0511c5fb 100644 --- a/Sources/CryptoBoringWrapper/Util/RandomBytes.swift +++ b/Sources/CryptoBoringWrapper/Util/RandomBytes.swift @@ -19,7 +19,7 @@ extension UnsafeMutableRawBufferPointer { return } - #if canImport(Darwin) || os(Linux) || os(Android) || os(Windows) + #if canImport(Darwin) || os(Linux) || os(Android) || os(Windows) || os(FreeBSD) var rng = SystemRandomNumberGenerator() precondition(count <= self.count) diff --git a/Tests/CryptoTests/Encodings/DERTests.swift b/Tests/CryptoTests/Encodings/DERTests.swift index 38bcfbca..02ce6bbd 100644 --- a/Tests/CryptoTests/Encodings/DERTests.swift +++ b/Tests/CryptoTests/Encodings/DERTests.swift @@ -49,7 +49,7 @@ class DERTests: XCTestCase { } func randomBytes(count: Int) -> [UInt8] { - #if canImport(Darwin) || os(Linux) || os(Android) || os(Windows) + #if canImport(Darwin) || os(Linux) || os(Android) || os(Windows) || os(FreeBSD) var rng = SystemRandomNumberGenerator() return (0.. Date: Mon, 16 Dec 2024 13:52:12 +0100 Subject: [PATCH 2/2] Improve DocC landing pages (#313) Improve DocC landing pages by mimicking Apple's CryptoKit docs ### Motivation: Right now the DocC docs group all APIs by protocols, structures and enums. By adding a topics section in the landing page we can group them by type ("Ciphers", "Public key cryptography", etc.) exactly in the way Apple does in [CryptoKit docs](https://developer.apple.com/documentation/cryptokit/). ### Modifications: - Fix DocC compilation errors in `_CryptoExtras` - Add topics section in `_CryptoExtras` landing page - Add topics section in `Crypto` landing page ### Result: APIs will be grouped by type. --------- Co-authored-by: Cory Benfield --- Sources/Crypto/Docs.docc/index.md | 44 ++++++++++++++++++- Sources/_CryptoExtras/Docs.docc/index.md | 20 +++++++++ .../_CryptoExtras/RSA/RSA+BlindSigning.swift | 4 +- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/Sources/Crypto/Docs.docc/index.md b/Sources/Crypto/Docs.docc/index.md index e44b543b..93185778 100644 --- a/Sources/Crypto/Docs.docc/index.md +++ b/Sources/Crypto/Docs.docc/index.md @@ -9,4 +9,46 @@ Swift Crypto provides a Swift library for common cryptographic operations. It is * `Crypto` - an open-source implementation of a substantial portion of the API of [Apple CryptoKit](https://developer.apple.com/documentation/cryptokit) suitable for use on Linux platforms. It enables cross-platform or server applications with the advantages of CryptoKit. * `CryptoExtras` - a collection of additional cryptographic primitives and utilities that are not part of CryptoKit but useful in a server environment. -Swift Crypto is built on top of [BoringSSL](https://boringssl.googlesource.com/boringssl/), Google's fork of OpenSSL. The current features of Swift Crypto cover key exchange, key derivation, encryption and decryption, hashing, message authentication, and more. \ No newline at end of file +Swift Crypto is built on top of [BoringSSL](https://boringssl.googlesource.com/boringssl/), Google's fork of OpenSSL. The current features of Swift Crypto cover key exchange, key derivation, encryption and decryption, hashing, message authentication, and more. + +## Topics + +### Cryptographically secure hashes + +- ``HashFunction`` +- ``SHA512`` +- ``SHA384`` +- ``SHA256`` + +### Message authentication codes + +- ``HMAC`` +- ``SymmetricKey`` +- ``SymmetricKeySize`` + +### Ciphers + +- ``AES`` +- ``ChaChaPoly`` + +### Public key cryptography + +- ``Curve25519`` +- ``P521`` +- ``P384`` +- ``P256`` +- ``SharedSecret`` +- ``HPKE`` + +### Key derivation functions + +- ``HKDF`` + +### Errors + +- ``CryptoKitError`` +- ``CryptoKitASN1Error`` + +### Legacy algorithms + +- ``Insecure`` diff --git a/Sources/_CryptoExtras/Docs.docc/index.md b/Sources/_CryptoExtras/Docs.docc/index.md index d09b57cf..50b5eca5 100644 --- a/Sources/_CryptoExtras/Docs.docc/index.md +++ b/Sources/_CryptoExtras/Docs.docc/index.md @@ -2,4 +2,24 @@ Provides additional cryptographic APIs that are not available in CryptoKit (and therefore the core Crypto library). +## Overview +`CryptoExtras` is a collection of additional cryptographic primitives and utilities that are not part of CryptoKit but useful in a server environment. + +## Topics + +### Ciphers + +- ``_CryptoExtras/Crypto/AES`` + +### Public key cryptography + +- ``_RSA`` + +### Key derivation functions + +- ``KDF`` + +### Legacy algorithms + +- ``_CryptoExtras/Crypto/Insecure`` diff --git a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift b/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift index a197704e..cf866dce 100644 --- a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift +++ b/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift @@ -410,7 +410,7 @@ extension _RSA.BlindSigning.PublicKey { /// Prepare a message to be signed using the blind signing protocol. /// /// - Parameter message: The message to be signed. - /// - Parameter parameters: Parameters used in the blind signing protocol. + /// /// - Returns: A prepared message, modified according to the parameters provided. /// /// - Seealso: [RFC 9474: Prepare](https://www.rfc-editor.org/rfc/rfc9474.html#name-prepare). @@ -440,7 +440,7 @@ extension _RSA.BlindSigning.PublicKey { /// /// - Parameter signature: The signature of the blinded message. /// - Parameter message: The message to be signed. - /// - Parameter blindInverse: The inverse from the message blinding. + /// - Parameter blindingInverse: The inverse from the message blinding. /// - Returns: The signature of the message. /// /// - Seealso: [RFC 9474: Finalize](https://www.rfc-editor.org/rfc/rfc9474.html#name-finalize).