Swift Crypto Extras

There is a need, among server-side apps, for cryptographic functionality outside of what Swift Crypto currently provides. For Vapor specifically, some examples of this include RSA (MySQL and JWT) and Bcrypt (Vapor). In order to provide RSA specifically, Vapor, like SwiftCrypto itself, embeds a namespaced version of BoringSSL.

Vapor cannot use SwiftCrypto's private copy of BoringSSL directly because BoringSSL does not have a stable API. This means any Vapor app using packages like JWTKit or MySQL will need to download and compile BoringSSL n times. Not only does this increase build time and binary size, it also presents extra maintenance burden for our packages.

I have a couple of ideas for avoiding these issues:

1: SwiftCrypto adds a new module, CryptoExtras, that offers an API for highly requested features like RSA. This API could be listed as unsafe. By being in a separate, OSS-only module, this would avoid breaking API compatibility with Apple's proprietary CryptoKit library.

This solution is ideal as it would minimize the copies of BoringSSL to one.

2: This idea is essentially the same idea as (1) but with the module in a separate package. This would require two copies of BoringSSL, but would at least prevent the number from continuing to grow beyond that. This may be a reasonable compromise if there is concern about offering an unsafe / unofficial module as a part of the official SwiftCrypto package.

I'm very interested for feedback on these ideas and also: What else should be included in a CryptoExtras module?

Thanks!

12 Likes

Anything necessary for parsing and validating HTTPS certs, please. Something that might be useful in creating an alternative to the Security types used by URLSession on Apple platforms. That is, if this CryptoExtras module might be suitable as a FoundationNetworking dependency.

5 Likes

I'm very interested for feedback on these ideas and also: What else should be included in a CryptoExtras module?

I'd be interested in seeing the bignum support being exposed. I'm currently rolling another copy of BoringSSL for my own bignum package which is then used to build a Secure Remote Password protocol for communication with AWS Cognito.

I like the idea of having a CryptoExtras module with some functionality.

I'm very interested for feedback on these ideas and also: What else should be included in a CryptoExtras module?

High on my list would be

  • Support for RSA key generation.
  • Support for X509 certificates (Certificates and CSR's). Ideally, this would play nice with NIOSSLCertificate.
  • SHA3 (Keccak) support, at which point we could also have a non-HMAC MAC because SHA3 doesn't need a nested construction. (See KMAC).
  • Password hashing functions. Those used to be present in CommonCrypto, but not in CryptoKit. PBKDF2 and Argon2.
2 Likes

Obviously secp256k1, Schnorr Signatures and ECIES

Huge +1 to this. Breaking away from CryptoKit and avoiding being constrained to OS releases is a must in my view.

In terms of which solution to go for it probably depends on what the Swift Crypto team are happy to support. 2 copies isn't that bad - the compilation times aren't terrible having done it. Option 2 with a view/plan to moving to option 1 would be a good compromise.

In terms of what functionality to add I think we need to be careful and slowly roll out additional functionality. There's a chance it becomes a free-for-all, which makes versioning the API hard. I think a clear goal or aim for the package would be good to state so everyone knows where we stand. Is the package going to be focused on server apps, client apps, both? Are we going off APIs for Blockchain (this was a common request when Swift Crypto was launched) and do we want to become a general Crypto library, a la CryptoSwift?

3 Likes

Agreed. Once we know if a separate module or repo that can diverge from CryptoKit is possible we can start to discuss how exactly that would work. Pitches for additional functionality could go through the Swift "server evolution" (SSWG) process or a new one. Making sure new additions are vetted well is critical. I think this could also be a proving ground for APIs that CryptoKit proper could adopt. Maybe similar to how StandardLibraryPreview works.

1 Like

I have been in need of similar algorithms mentioned here, and have existing implementations. I have a completed PBKDF2 implementation and a partially completed RSA implementation thanks to the help of @graskind.

I've got two questions on this topic:

  • What is the deciding factor whether a cryptographic standard makes it into CryptoExtras?
  • What happens when a cryptographic standard such as SHA3 makes it into CryptoKit itself? And what happens when the APIs don't overlap?

I've been implementing some Signal specifications, Double-Ratchet comes to mind. I feel like it'd be a great addition in a CryptoExtra's lib, but it's also a pretty specific need. What happens to these implementations?

1 Like

Any updated thoughts here after a few years? Especially with regards to password hashing (Argon2, etc.), there really aren't any great options available, would love to see a better-supported community extras package.

There is a CrypoExtras module in Swift Crypto that has started to include some extra things that aren't in Swift Crypto main - swift-crypto/Sources/_CryptoExtras at main · apple/swift-crypto · GitHub

IMO Argon2 shouldn't be part of this as it's not much of an issue pulling in another library if you want to use Argon2. Whether a good library exists is another question but I'd love to see one pitched to the SSWG

Isn't that true of virtually any standard? I know SwiftCrypto is meant to be a reimplementation of CryptoKit, but shouldn't the extras be more open than the main module? It would be really nice if we didn't have to pull in tons of frameworks of unknown quality with different API designs just to use a different encryption.

2 Likes