Closed mattsb42-aws closed 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.
See also #142 - if the caller provides an encryption context it should also be verified before releasing any plaintext.
@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.
Okay fair enough - so my statement isn't incorrect, it's just not relevant here.
This is specified in #149
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: