To be clear - this post is not supposed to be a criticism of Swift Crypto but more a call for discussion and some constructive feedback.
When Swift Crypto was introduced the crypto story on non-Apple platforms was painful. You either relied on the system providing OpenSSL (and the correct version of OpenSSL without it updating from underneath you) and knowing the special incantation of compiler flags to make linking work, or you built your own copy of LibreSSL and friends and took the compile time hit. The issue was that with no central recommended option, you ended up with a combination of the two and the terrible compile times to show for it.
The situation these days with Swift Crypto now is much nicer. Most libraries in the ecosystem now use it and with the additions of Crypto Extras, most libraries can switch over to one crypto library and reap the benefits.
However, it now very much feels like Swift Crypto is both constrained by being a client library first and foremost and frustratingly limited by the development speed of Apple platforms, which is an outlier in the server world. Simple things, like Sendability annotations, don't exist (an issue was raised over a year and a half ago(!) and still no movement on it for something that on the Linux side is as simple as marking types with the protocol) whilst APIs that are required by Apple services, such as Sign in with Apple and PassKit, can't be added because it doesn't make sense to add to the client library on Apple platforms.
There's also an awkward distinction where Apple platforms have an OS optimised implementation but other platforms have their own implementation, furthering the perception that Swift on Apple platforms is not equal to Swift on other platforms. Swift is a cross-platform language that is a successor to other systems languages and it should provide a complete crypto library that is the same on all platforms.
Other issues like discoverability of Crypto Extras APIs, documentation of the whole package and needing to know implementation details of CryptoKit are all small annoyances that add up to annoying paper cuts. Just this week I was working with a client that was trying to implement signing on Cloudfront who had spent a while working with the Security framework that provided some of the unnecessary APIs and got stuck simply because they didn't know RSA operations existed CryptoExtras.
So I would like a propose a few stages for discussion:
- Rename
_CryptoExtras
toCryptoExtras
- the underscore technically means the API is unstable and subject to change. It would be nice to set a line in the sand and fully support the new APIs that are being used. - Reduce the barrier for getting new APIs added to CryptoExtras - historically adding new APIs even to CrypoExtras has had quite a high barrier which causes problems for people needing APIs that exist in BoringSSL but aren't exposed because it provides no versioning guarantees.
- Integrate CryptoExtras into Crypto itself - the split of the library is confusing and is not clear from the outside if you don't have experience of iOS which API should live where. This can be solved with improved documentation but again, is another paper cut that would be nice not to deal with.
- Break away from CryptoKit - whilst it has served the ecosystem well and the intention is well understood, it's causing more and more issues. It would be great to live in a world where no RSA APIs are offered because it's insecure and shouldn't be used anymore, the reality is that many services that need to be used in the server world (looking at you SIWA) still use it, so we need APIs for it. Breaking away from the constraints of CryptoKit would allow for better development times, improved APIs and a nicer ecosystem. Anyone wanting to just build for Apple platforms can use CryptoKit, anyone wanting to build cross-platform libraries and apps can use Swift Crypto, which should become the defacto library for stuff under Swiftlang (i.e. not for Apple platforms). This also might provide some incentives for reimplementing parts of the API in Swift natively rather than needing to bridge through to a C library.
It would be great to see points 1 and 2 addressed in the near future, I'm not expecting quick changes for 3 and 4 but hopefully others can chime in with their thoughts, points of views and nuances I've invariably overlooked.