awslabs / aws-encryption-sdk-specification

AWS Encryption SDK Specification
Other
30 stars 27 forks source link

Add implementation guidance on when to decrypt data #136

Closed mattsb42-aws closed 4 years ago

mattsb42-aws commented 4 years ago

One of the promises that the ESDK makes is that it will not release plaintext until it has been authenticated. For framed messages this means authenticating using the GCM tag for a frame, while for unframed messages this means authenticating using the GCM tag for the message body.

We should add specific implementation guidance on the order of operations to follow. Specifically:

  1. Read entire ciphertext (one frame or the entire unframed message body) into a ciphertext buffer.
  2. Decrypt the ciphertext into a plaintext buffer and authenticate using the tag.
  3. Release the plaintext to the caller.
mattsb42-aws commented 4 years ago

background:

GCM is just CTR+GMAC, and you have to completely process the ciphertext before you can authenticate the GMAC tag. The way most GCM implementations work is that they stream the plaintext out to you as you go through decrypting the ciphertext, then when you think you’re done you can authenticate the message and AAD against the tag. This pattern is necessary for low-resource-overhead streams but is problematic because it means that you are releasing the plaintext to the caller before you have authenticated it, thereby losing a lot of the value that GCM provides over CTR. To mitigate this issue, we add this buffering layer on top of the underlying GCM implementation, and only start releasing plaintext once we have authenticated the entire ciphertext.

robin-aws commented 4 years ago

See also #142 - if the caller provides an encryption context it should also be verified before releasing any plaintext.

mattsb42-aws commented 4 years ago

@robin-aws I think that is best handled under a different scope. The scope of this specific issue is meant to be for the component that is handling the message body. By definition, by the time the client reaches the body, the encryption context is no longer in play. We have a few different levers we can pull on the encryption context (keyring, header auth), and we should perhaps make more specific statements about what MUST and SHOULD happen at each of those stages, but I do not think that #142 is relevant to this specific scope.

robin-aws commented 4 years ago

Okay fair enough - so my statement isn't incorrect, it's just not relevant here.

lavaleri commented 4 years ago

This is specified in #149