Skip to content

Commit 0411996

Browse files
3405691582Lukasa
andauthored
OpenBSD support. (#349)
OpenBSD 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 (_not necessary_) #### If you've made changes to `gyb` files - [X] I've run `.script/generate_boilerplate_files_with_gyb` and included updated generated files in a commit of this pull request (_not applicable_) ### Motivation: swift-crypto is a required dependency for swift-package-manager, and must build and run on OpenBSD. ### Modifications: OpenBSD support for cmake/swiftpm. * Add to patterns for CMakeLists. Also provide a helpful error so future porters have a slightly better idea of what might need to be updated. * Proactively reverse sense in some system name checks so they read as "if not Darwin". This is likely safer to do here than elsewhere since there are likely not going to be other platforms for which swift-crypto already exists. * Add to Package.swift ManagedBuffer.capacity is unavailable on OpenBSD. ManagedBuffer.capacity depends on malloc introspection (e.g., `malloc_size`), which is not available on this platform -- and is thus marked as such. Here, SecureBytes uses a ManagedBuffer in Backing. We have capacity tracked in the BackingHeader, and most of the references to the ManagedBuffer.capacity property can be replaced with references to the capacity in the header. However, since capacity in the header is marked as internal which conflicts with some of the @inline functions, so we must change those to @usableFromInline for the platform as well. Add conditional for RandomBytes. Required for tests to build on OpenBSD. ### Result: swift-crypto builds and runs on OpenBSD. --------- Co-authored-by: Cory Benfield <[email protected]>
1 parent e9a2ec1 commit 0411996

File tree

7 files changed

+38
-23
lines changed

7 files changed

+38
-23
lines changed

Package.swift

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ if development || isFreeBSD {
5656
Platform.android,
5757
Platform.windows,
5858
Platform.wasi,
59+
Platform.openbsd,
5960
]
6061
swiftSettings = [
6162
.define("CRYPTO_IN_SWIFTPM"),

Sources/CCryptoBoringSSL/CMakeLists.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL Darwin AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x
281281
gen/crypto/chacha-x86_64-apple.S
282282
gen/crypto/chacha20_poly1305_x86_64-apple.S
283283
gen/crypto/md5-x86_64-apple.S)
284-
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD" AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64")
284+
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|OpenBSD" AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64")
285285
target_sources(CCryptoBoringSSL PRIVATE
286286
gen/bcm/aes-gcm-avx10-x86_64-linux.S
287287
gen/bcm/aesni-gcm-x86_64-linux.S
@@ -318,7 +318,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm
318318
gen/bcm/vpaes-armv8-apple.S
319319
gen/crypto/chacha-armv8-apple.S
320320
gen/crypto/chacha20_poly1305_armv8-apple.S)
321-
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
321+
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|OpenBSD" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
322322
target_sources(CCryptoBoringSSL PRIVATE
323323
gen/bcm/aesv8-armv8-linux.S
324324
gen/bcm/aesv8-gcm-armv8-linux.S
@@ -334,6 +334,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD" AND CMAKE_SYSTEM_PROCES
334334
gen/bcm/vpaes-armv8-linux.S
335335
gen/crypto/chacha-armv8-linux.S
336336
gen/crypto/chacha20_poly1305_armv8-linux.S)
337+
else()
338+
message(FATAL_ERROR "platform sources are not defined here")
337339
endif()
338340

339341
target_include_directories(CCryptoBoringSSL PUBLIC

Sources/Crypto/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ add_library(Crypto
9797
target_compile_definitions(Crypto PRIVATE
9898
"$<$<COMPILE_LANGUAGE:Swift>:CRYPTO_IN_SWIFTPM>")
9999

100-
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)
100+
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
101101
target_compile_definitions(Crypto PRIVATE
102102
"$<$<COMPILE_LANGUAGE:Swift>:CRYPTO_IN_SWIFTPM_FORCE_BUILD_API>")
103103
endif()

Sources/Crypto/Util/SecureBytes.swift

+24-12
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ extension SecureBytes {
6262
@inlinable
6363
mutating func append<C: Collection>(_ data: C) where C.Element == UInt8 {
6464
let requiredCapacity = self.count + data.count
65-
if !isKnownUniquelyReferenced(&self.backing) || requiredCapacity > self.backing.capacity {
65+
let backingCapacity = self.backing.allocatedCapacity
66+
if !isKnownUniquelyReferenced(&self.backing) || requiredCapacity > backingCapacity {
6667
let newBacking = Backing.create(capacity: requiredCapacity)
6768
newBacking._appendBytes(self.backing, inRange: 0..<self.count)
6869
self.backing = newBacking
@@ -72,7 +73,8 @@ extension SecureBytes {
7273

7374
@usableFromInline
7475
mutating func reserveCapacity(_ n: Int) {
75-
if self.backing.capacity >= n {
76+
let backingCapacity = self.backing.allocatedCapacity
77+
if backingCapacity >= n {
7678
return
7779
}
7880

@@ -157,8 +159,9 @@ extension SecureBytes: RangeReplaceableCollection {
157159
@inlinable
158160
mutating func replaceSubrange<C: Collection>(_ subrange: Range<Index>, with newElements: C) where C.Element == UInt8 {
159161
let requiredCapacity = self.backing.count - subrange.count + newElements.count
162+
let backingCapacity = self.backing.allocatedCapacity
160163

161-
if !isKnownUniquelyReferenced(&self.backing) || requiredCapacity > self.backing.capacity {
164+
if !isKnownUniquelyReferenced(&self.backing) || requiredCapacity > backingCapacity {
162165
// We have to allocate anyway, so let's use a nice straightforward copy.
163166
let newBacking = Backing.create(capacity: requiredCapacity)
164167

@@ -292,7 +295,7 @@ extension SecureBytes {
292295
targetPtr.copyMemory(from: bytesPtr)
293296
}
294297
backing.count = bytesPtr.count
295-
precondition(backing.count <= backing.capacity)
298+
precondition(backing.count <= backing.allocatedCapacity)
296299
return backing
297300
}
298301
}
@@ -343,6 +346,15 @@ extension SecureBytes {
343346

344347
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *)
345348
extension SecureBytes.Backing {
349+
@usableFromInline
350+
var allocatedCapacity: Int {
351+
#if os(OpenBSD)
352+
return self.header.capacity
353+
#else
354+
return self.capacity
355+
#endif
356+
}
357+
346358
func replaceSubrangeFittingWithinCapacity<C: Collection>(_ subrange: Range<Int>, with newElements: C) where C.Element == UInt8 {
347359
// This function is called when have a unique reference to the backing storage, and we have enough room to store these bytes without
348360
// any problem. We have one pre-existing buffer made up of 4 regions: a prefix set of bytes that are
@@ -362,7 +374,7 @@ extension SecureBytes.Backing {
362374
// for R1 and then move the suffix, as if R2 is larger than R1 we'll have thrown some suffix bytes away. So we have
363375
// to move suffix first. What we do is take the bytes in suffix, and move them (via memmove). We can then copy
364376
// R2 in, and feel confident that the space in memory is right.
365-
precondition(self.count - subrange.count + newElements.count <= self.capacity, "Insufficient capacity")
377+
precondition(self.count - subrange.count + newElements.count <= self.allocatedCapacity, "Insufficient capacity")
366378

367379
let moveDistance = newElements.count - subrange.count
368380
let suffixRange = subrange.upperBound..<self.count
@@ -375,7 +387,7 @@ extension SecureBytes.Backing {
375387
/* private but inlinable */ func _appendBytes<C: Collection>(_ bytes: C) where C.Element == UInt8 {
376388
let byteCount = bytes.count
377389

378-
precondition(self.capacity - self.count - byteCount >= 0, "Insufficient space for byte copying, must have reallocated!")
390+
precondition(self.allocatedCapacity - self.count - byteCount >= 0, "Insufficient space for byte copying, must have reallocated!")
379391

380392
let lowerOffset = self.count
381393
self._withVeryUnsafeMutableBytes { bytesPtr in
@@ -389,8 +401,8 @@ extension SecureBytes.Backing {
389401
/// is not enough room.
390402
/* private but inlinable */ func _appendBytes(_ backing: SecureBytes.Backing, inRange range: Range<Int>) {
391403
precondition(range.lowerBound >= 0)
392-
precondition(range.upperBound <= backing.capacity)
393-
precondition(self.capacity - self.count - range.count >= 0, "Insufficient space for byte copying, must have reallocated!")
404+
precondition(range.upperBound <= backing.allocatedCapacity)
405+
precondition(self.allocatedCapacity - self.count - range.count >= 0, "Insufficient space for byte copying, must have reallocated!")
394406

395407
backing.withUnsafeBytes { backingPtr in
396408
let ptrSlice = UnsafeRawBufferPointer(rebasing: backingPtr[range])
@@ -411,11 +423,11 @@ extension SecureBytes.Backing {
411423
/* private but usableFromInline */ func _moveBytes(range: Range<Int>, by delta: Int) {
412424
// We have to check that the range is within the delta, as is the new location.
413425
precondition(range.lowerBound >= 0)
414-
precondition(range.upperBound <= self.capacity)
426+
precondition(range.upperBound <= self.allocatedCapacity)
415427

416428
let shiftedRange = (range.lowerBound + delta)..<(range.upperBound + delta)
417429
precondition(shiftedRange.lowerBound > 0)
418-
precondition(shiftedRange.upperBound <= self.capacity)
430+
precondition(shiftedRange.upperBound <= self.allocatedCapacity)
419431

420432
self._withVeryUnsafeMutableBytes { backingPtr in
421433
let source = UnsafeRawBufferPointer(rebasing: backingPtr[range])
@@ -428,7 +440,7 @@ extension SecureBytes.Backing {
428440
@inlinable
429441
/* private but inlinable */ func _copyBytes<C: Collection>(_ bytes: C, at offset: Int) where C.Element == UInt8 {
430442
precondition(offset >= 0)
431-
precondition(offset + bytes.count <= self.capacity)
443+
precondition(offset + bytes.count <= self.allocatedCapacity)
432444

433445
let byteRange = offset..<(offset + bytes.count)
434446

@@ -460,7 +472,7 @@ extension SecureBytes.Backing: ContiguousBytes {
460472
/// Very unsafe in the sense that this points to uninitialized memory. Used only for implementations within this file.
461473
@inlinable
462474
/* private but inlinable */ func _withVeryUnsafeMutableBytes<T>(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T {
463-
let capacity = self.capacity
475+
let capacity = self.allocatedCapacity
464476

465477
return try self.withUnsafeMutablePointerToElements { elementsPtr in
466478
return try body(UnsafeMutableRawBufferPointer(start: elementsPtr, count: capacity))

Sources/CryptoBoringWrapper/Util/RandomBytes.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extension UnsafeMutableRawBufferPointer {
2020
return
2121
}
2222

23-
#if canImport(Darwin) || os(Linux) || os(Android) || os(Windows) || os(FreeBSD)
23+
#if canImport(Darwin) || os(Linux) || os(Android) || os(Windows) || os(FreeBSD) || os(OpenBSD)
2424
var rng = SystemRandomNumberGenerator()
2525
precondition(count <= self.count)
2626

Sources/_CryptoExtras/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ add_library(_CryptoExtras
6969

7070
target_compile_options(_CryptoExtras PRIVATE -DCRYPTO_IN_SWIFTPM)
7171

72-
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)
72+
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
7373
target_compile_options(_CryptoExtras PRIVATE -DCRYPTO_IN_SWIFTPM_FORCE_BUILD_API)
7474
endif()
7575

Tests/CryptoTests/SecureBytes/SecureBytesTests.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -122,28 +122,28 @@ final class SecureBytesTests: XCTestCase {
122122

123123
func testResizingByMakingLarger() {
124124
var base = SecureBytes(count: 12)
125-
XCTAssertGreaterThanOrEqual(base.backing.capacity, 16)
125+
XCTAssertGreaterThanOrEqual(base.backing.allocatedCapacity, 16)
126126
XCTAssertEqual(base.count, 12)
127127

128128
base.append(contentsOf: 0..<16)
129-
XCTAssertGreaterThanOrEqual(base.backing.capacity, 32)
129+
XCTAssertGreaterThanOrEqual(base.backing.allocatedCapacity, 32)
130130
XCTAssertEqual(base.count, 28)
131131

132132
base.append(contentsOf: 0..<4)
133-
XCTAssertGreaterThanOrEqual(base.backing.capacity, 32)
133+
XCTAssertGreaterThanOrEqual(base.backing.allocatedCapacity, 32)
134134
XCTAssertEqual(base.count, 32)
135135
}
136136

137137
func testCountInitializerGeneratesSomewhatRandomData() {
138138
let base = SecureBytes(count: 16)
139-
XCTAssertGreaterThanOrEqual(base.backing.capacity, 16)
139+
XCTAssertGreaterThanOrEqual(base.backing.allocatedCapacity, 16)
140140
XCTAssertEqual(base.count, 16)
141141
XCTAssertNotEqual(Array(repeating: UInt8(0), count: 16), Array(base))
142142
}
143143

144144
func testBackingBytesAreAppropriatelySized() {
145145
var base = SecureBytes(repeating: 0, count: 10)
146-
XCTAssertGreaterThanOrEqual(base.backing.capacity, 16)
146+
XCTAssertGreaterThanOrEqual(base.backing.allocatedCapacity, 16)
147147

148148
base.withUnsafeBytes { XCTAssertEqual($0.count, 10) }
149149
base.withUnsafeMutableBytes { XCTAssertEqual($0.count, 10) }
@@ -164,7 +164,7 @@ final class SecureBytesTests: XCTestCase {
164164
initializedCapacity = 4
165165
}
166166

167-
XCTAssertGreaterThanOrEqual(base.backing.capacity, 8)
167+
XCTAssertGreaterThanOrEqual(base.backing.allocatedCapacity, 8)
168168
XCTAssertEqual(Array(base), [1, 2, 3, 4])
169169

170170
func testThrowingInitialization() throws {

0 commit comments

Comments
 (0)