Native implementations and BoringSSL-backed Apple platform deployments

There are two big issues I didn't see addressed in the Swift Crypto docs made available so far.

  1. Is it a goal, explicit non-goal, or undecided to implement crypto primitives and algorithms in native Swift, eventually removing the need for BoringSSL? Personally, I think it would be a benefit to the language and library to move in that direction, but I'd like to know if PRs in that direction would be accepted.
  2. Is it a goal, explicit non-goal, or undecided to enable the use of SwiftCrypt to backwards deploy the CryptoKit APIs on Apple's platforms? It seems you can build the BoringSSL version for Apple platforms, but I wonder if work towards making it easier to backward deploy would be accepted. If not, the CryptoSwift library would likely continue to be my goto on Apple platforms, especially if it, too, adopts a CryptoKit compatible API layer.
2 Likes

Hi @Jon_Shier,

I was at dotswift conference where @lukasa announce swift-crypto.

Swift-crypto will use CryptoKit on macOS and BoringSSL on other platforms.

I don’t know for the second question but I don’t have the felling that apple want to replace boring ssl. This might be du to the maintenance cost of support and implementation.

It's certainly an interesting choice to open-source the CryptoKit APIs but not the implementation, considering that Apple usually publishes their crypto libraries.

Whether or not it is the goal of this project to provide pure-Swift implementations (I guess not), it at least provides a standard API that you can experiment with forking and re-implementing.

Now let's wait until Combine gets a similar open-source treatment :pleading_face:

2 Likes

Frankly I'm surprised Combine wasn't open sourced first, considering it seems like it would be much easier to do so, and far less risky.

1 Like

Off-topic, but my fingers are :crossed_fingers: that if import Crypto re-imports CryptoKit on darwin that we might eventually see something for Combine as already mentioned upthread and maybe import UI that re-imports SwiftUI on darwin.

3 Likes

That's my hope for Combine and SwiftUI as well, but the open sourcing of both of those projects would likely have the same questions I've posed here.

  1. Will work towards Swift-native solutions be accepted?
  2. Will work towards making backwards deployments on Apple platforms possible be accepted?

I think these questions are answered in the blog post at least in CryptoKit context: Swift.org - Introducing Swift Crypto

Evolving Swift Crypto

As Swift Crypto’s core goal is to provide a cross-platform solution for using Apple CryptoKit’s APIs on a wider range of platforms, the API will naturally follow the evolution of Apple CryptoKit itself. However, as Swift Crypto is an open source project, there is some scope for proposing API directly to Swift Crypto. Depending on the scope of these APIs, ** they may also be considered for parallel implementation in Apple CryptoKit. **

Thanks for reaching out Jon!

It’s a “nice to have”. Where we can reasonably do so we will implement primitives in Swift: for example, HKDF is written entirely in Swift. However, Swift has some limitations for cryptographic implementations. Some of these are capable of being improved upon: for example, we can work on tools for the language to make writing constant time code easier.

Some limitations may never be passed. For example, it is very hard to get great performance from cryptography without assembly language acceleration. While this is definitely a “never say never” space, I wouldn’t hold my breath to see us adopt pure-Swift for all primitives. That performance just unlocks too many use-cases to give up.

At this time it’s a non-goal. We are open to discussing this with the community, but enabling a back-deployment story has a number of risks. It makes vulnerability mitigation stories very complex if some primitives silently come from CryptoKit and others from Swift Crypto’s OSS backend. The joy of the current model is that you can continue to assume the platform will supply security fixes on Apple platforms: with back-deployment, that’s less true.

5 Likes

While I think language support for assembly literals seems necessary for Swift to have a complete systems programming story, I agree there will be some performance difference in certain areas for quite some time. However, I guess my overall proposal would be to allow users to make that choice, effectively offering a third distribution. Then the choices would be: CryptoKit overlay on Apple platforms, maximum performance BoringSSL-based distribution for other platforms, and a Swift-native distribution for those who don't need maximum performance but value a simpler dependency graph.

Actually, I'd argue that enabling backward deployment provides greater mitigation, not less, as it allows developers to deploy fixes to platforms which are no longer getting security updates. Additionally, tooling like SPM can warn or even error out when integrating library versions with vulnerabilities, it's just a matter of investing the effort to do so.

Even if you don't accept that argument, this library will likely end up being used that way anyway, officially supported or not, especially if BoringSSL becomes an optional dependency, as mentioned above.

I'm not sure about everyone, but I don't understand "pure Swift" to mean "no inline assembly"; I read it to mean "not wrapping C code". Of course there will be hardware-specific things which can only be accessed via asm.

The only tangible benefits to having things be pure Swift rather than C are (IIUC): broader generics support (e.g. sequences/collections would not need to be contiguous), and potentially enabling high-level optimisations via SIL (that's why SIL exists, right?). I'm not sure, but they don't sound like major factors for cryptography.

I still hope that it will be in the scope of Swift 6.

I'd like to note that the assembly use-case is not just for hardware specific features. Often assembly is required to limit the scope of side channels, or to ensure high performance data access patterns. As it does not involve a compiler, it is not possible for the compiler to regress the performance of such an implementation, and does not require a "sufficiently smart" optimising compiler. These performance benefits are very real, and can unlock orders of magnitude of performance improvement in common algorithms such as AES.

In principle we could try to burn down the amount of C in the codebase, but I am not confident in how much value that unlocks. For vulnerability management reasons we need to continue to bring in the assembly language implementations of the base primitives. This means we don't gain much simplification in dependency management (we still have a BoringSSL dependency).

Additionally, as you note, I think the gains it brings us are fairly minor. Don't get me wrong, I'd like to see us burn down the amount of C in this project over time, but I don't consider it a high priority to do so. Interested contributors are welcome to take a swing at it though!

4 Likes

Actually this would be for those who don't need maximum performance nor maximal security. Having an implementation that doesn't support constant time algorithm or side channel attack protection is unsafe, not just slower.

Moreover, the cost of maintaining a third implementation would be too high for the benefit it bring IMHO.

Interesting. CombineX use the same solution as SwiftCrypto, and it support backwards deployment by translating environment variable to compilation conditions. They call it Combine Compatible Package.