[][src]Function ring::aead::open_in_place

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>

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.)