Function ring::aead::open_in_place
source · [−]pub fn open_in_place<'a>(
key: &OpeningKey,
nonce: Nonce,
aad: Aad<'_>,
in_prefix_len: usize,
ciphertext_and_tag_modified_in_place: &'a mut [u8]
) -> Result<&'a mut [u8], Unspecified>
Expand description
Authenticates and decrypts (“opens”) data in place.
The input may have a prefix that is in_prefix_len
bytes long; any such
prefix is ignored on input and overwritten on output. The last
key.algorithm().tag_len()
bytes of ciphertext_and_tag_modified_in_place
must be the tag. The part of ciphertext_and_tag_modified_in_place
between
the prefix and the tag is the input ciphertext.
When open_in_place()
returns Ok(plaintext)
, the decrypted output is
plaintext
, which is
&mut ciphertext_and_tag_modified_in_place[..plaintext.len()]
. That is,
the output plaintext overwrites some or all of the prefix and ciphertext.
To put it another way, the ciphertext is shifted forward in_prefix_len
bytes and then decrypted in place. To have the output overwrite the input
without shifting, pass 0 as in_prefix_len
.
When open_in_place()
returns Err(..)
,
ciphertext_and_tag_modified_in_place
may have been overwritten in an
unspecified way.
The shifting feature is useful in the case where multiple packets are being reassembled in place. Consider this example where the peer has sent the message “Split stream reassembled in place” split into three sealed packets:
Packet 1 Packet 2 Packet 3
Input: [Header][Ciphertext][Tag][Header][Ciphertext][Tag][Header][Ciphertext][Tag]
| +--------------+ |
+------+ +-----+ +----------------------------------+
v v v
Output: [Plaintext][Plaintext][Plaintext]
“Split stream reassembled in place”
Let’s say the header is always 5 bytes (like TLS 1.2) and the tag is always
16 bytes (as for AES-GCM and ChaCha20-Poly1305). Then for this example,
in_prefix_len
would be 5
for the first packet, (5 + 16) + 5
for the
second packet, and (2 * (5 + 16)) + 5
for the third packet.
(The input/output buffer is expressed as combination of in_prefix_len
and ciphertext_and_tag_modified_in_place
because Rust’s type system
does not allow us to have two slices, one mutable and one immutable, that
reference overlapping memory.)