apple / swift-crypto

Open-source implementation of a substantial portion of the API of Apple CryptoKit suitable for use on Linux platforms.
https://apple.github.io/swift-crypto
Apache License 2.0
1.45k stars 154 forks source link

Using this on Apple platforms before macOS 10.15 / iOS 13? #29

Open MrMage opened 4 years ago

MrMage commented 4 years ago

As far as I can tell, Swift Crypto requires macOS 10.15 / iOS 13 on Apple platforms, presumably due to the dependency on CryptoKit.

Would it be possible to use Swift Crypto on older Apple platforms by falling back to its BoringSSL backend in that case?

Lukasa commented 4 years ago

That's a good question. Thus far we've decided that it is best not to support that mode of operation for a few reasons.

Firstly, it fairly substantially changes the security risk profile of your application code. You no longer know which primitives come from where, so it is hard to be confident of where the responsibility falls for managing security updates.

Secondly, and more importantly, it greatly complicates the build story. Right now on Apple platforms the entire API surface of this module simply vanishes: we compile none of it. This works well because we re-export CryptoKit, which has all of those symbols. This is how we enable the transparent fallback.

If we wanted to shim in support for unsupported primitives, we'd have to instead have the API always unconditionally be there, and instead have runtime delegation to the CryptoKit implementation. This is quite a substantial change, and would require an enormous amount of implementation work. It also means that you'd need to bump your swift-crypto dependency to get access to new CryptoKit primitives, which is not required today.

Finally, it requires fairly drastic changes to the API definitions. Right now we share them verbatim across CryptoKit and Swift Crypto, which works because we don't remove the availability declarations. If we wanted to shim the API in we'd have to remove those availability declarations and replicate them in the backend code.

Ultimately, for the moment we think that on the balance of priorities it is out of scope for Swift Crypto to attempt to be a polyfill for CryptoKit. However, we do hear the concern, and we'll keep this use-case in mind going forward.

0xTim commented 4 years ago

Further discussions here https://forums.swift.org/t/native-implementations-and-boringssl-backed-apple-platform-deployments/33404/8?u=0xtim

MrMage commented 4 years ago

Thank you for the elaboration. As an alternative, would it be possible for me to fork the project, remove all references to CryptoKit, and always fall back to BoringSSL? That would provide me with a consistent implementation which always uses the same backend. I would need to make sure not to depend on CryptoKit myself anywhere, of course.

I can imagine that this would be a bad idea for a whole host of other reasons; would love to hear your thoughts on it.

Lukasa commented 4 years ago

I see no reason why that would fail, technically, but naturally that's a separate project to this one. You take on a lot of responsibility around security updates with BoringSSL, and you'd have to deal with any compatibility issues that arise due to the fact that we can safely depend on newer versions of the OS, but otherwise I can imagine that'll work. The joys of OSS. :grin:

Bouke commented 4 years ago

If we wanted to shim in support for unsupported primitives, we'd have to instead have the API always unconditionally be there, and instead have runtime delegation to the CryptoKit implementation.

I think you could use the conditional canImport instead, or am I missing something?

//current:
#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API

// becomes:
#if canImport(CryptoKit) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
Lukasa commented 4 years ago

canImport is a compile time check: it validates whether or not CryptoKit is in the SDK you are building against. However, to support older minimum deployment targets we’d need runtime checks, as it may not be present in the OS version your binary is actually running on. This is one of the sources of complexity I discussed above.

makleso6 commented 2 years ago

Hi! Any updates?

Lukasa commented 2 years ago

For now, I’m afraid not.