Open davidperrenoud opened 5 years ago
Related issue: https://github.com/jedisct1/swift-sodium/pull/173
@aidantwoods Do you have any thought about this?
It looks like specifying nonces when performing AEAD has been made optional in draft-paragon-paseto-rfc-01
which would allow to drop the Clibsodium dependency, though I do not know when this version of the RFC will be online or official.
Apologies for letting this linger a little.
I think your assessment in https://github.com/aidantwoods/swift-paseto/commit/517624c6374f5c0d070998d74588e5762688c53c#commitcomment-31681166 is correct: I had actually missed that the RFC text changed to make this optional, so yes I think we could drop Clibsodium
as a direct dependency while still technically following the spec (and dropping PASETO's way of guarding against an RNG failure would seem to be fine, given precautions already taken by libsodium: https://github.com/jedisct1/swift-sodium/pull/173#issuecomment-447327677).
I also would prefer not to depend on Clibsodium
directly anyway (orthogonally to this issue RE CocoaPods), since it isn't exactly ideal to be interacting directly with C
code if it can be avoided—that's swift-sodium's job.
One thing dropping Clibsodium
(and thus also being able to choose a nonce) may complicate, though, is unit testing. The unit tests currently use @testable import Paseto
which exposes an internal
part of the API, which permits specifying a nonce for the purpose of unit testing against the PASETO test vectors. But there would be no way to encrypt deterministically using just swift-sodium's AEAD interface.
So I'm just taking another look at this. Issues with unit testing aside, there's actually a blocking issue: the PASETO spec essentially requires deterministic encryption to be available via the necessity that the nonce that will be used for encryption is known prior to providing the additional data (used to calculate the value returned by Util.pae
):
https://github.com/aidantwoods/swift-paseto/blob/517624c6374f5c0d070998d74588e5762688c53c/Sources/Paseto/Implementations/Version2/V2Local.swift#L36-L41
This obviously means that (using what's available in the swift-sodium API), something like
let (cipherText, nonce) = sodium.aead.xchacha20poly1305ietf.encrypt(
message: message,
secretKey: key.material,
additionalData: ...
)
isn't going to work: since we can't yet calculate the value for the additionalData
parameter until the call returns. I don't think there's really a good way around this in the swift-sodium API either, without introducing a possibility for nonce reuse.
@aidantwoods You don't need the nonce, you can use random bytes as defined in paseto-rfc-01
:
2. Generate 24 random bytes from the OS's CSPRNG.
3. Optionally, calculate [...] This will be our nonce, "n".
* If this step is omitted, the output of step 2 is "n" instead.
4. Pack "h", "n", and "f" together (in that order) using PAE (see
Section 2.2). We'll call this "preAuth".
The confusing part is "If this step is omitted, the output of step 2 is "n" instead." This simply means that "n" is a nonce, not the nonce used to encrypt the payload.
@paragonie Could you rewrite steps 2-3 and merge these two options together to make this more obvious?
This still won't work because I need to use the same random bytes for the value of n
in calculating preAuth
. But I don't know which random bytes Swift-sodium will pick (and need them prior to encrypting for providing the correct the additional data value). If I just use random bytes that don't match the nonce libsodium assigns then decryption would fail.
Could you open an issue on PASETO's repository? You might be able to better describe the problem than me.
Thanks for opening that—I'm not entirely sure if the revised wording in draft-paragon-paseto-rfc-01
had the intent of accommodating this particular use case, so that issue should hopefully clarify things.
Oops, I didn't mean to let this sit for so long.
I think we should presume that the spec won't change to accommodate using non-deterministic aead variants. I noticed you added a .podspec
in your fork, did you manage to get something working that still incorporates Clibsodium?
Have you already tried supporting CocoaPods?
As far as I have tested, the only complicated point is the direct dependency on Clibsodium which is needed for 2 functions:
crypto_aead_xchacha20poly1305_ietf_encrypt
andcrypto_aead_xchacha20poly1305_ietf_decrypt
.Is there a reason why the
Aead
extensions from Swift-Sodium could not be used in place of these 2 functions?