fn split_into_records()

in src/aes128gcm.rs [368:419]


fn split_into_records(
    plaintext: &[u8],
    pad_length: usize,
    rs: usize,
) -> Result<PlaintextRecordIterator<'_>> {
    // Adjust for encryption overhead.
    if rs < ECE_AES128GCM_MIN_RS as usize {
        return Err(Error::InvalidRecordSize);
    }
    let rs = rs - ECE_TAG_LENGTH;
    // Ensure we have enough padding to give at least one byte of it to each record.
    // This is the only reason why we might expand the padding beyond what was requested.
    let mut min_num_records = plaintext.len() / (rs - 1);
    if plaintext.len() % (rs - 1) != 0 {
        min_num_records += 1;
    }
    let pad_length = std::cmp::max(pad_length, min_num_records);
    // Knowing the total data size, determines the number of records.
    let total_size = plaintext.len() + pad_length;
    let mut num_records = total_size / rs;
    let size_of_final_record = total_size % rs;
    if size_of_final_record > 0 {
        num_records += 1;
    }
    assert!(
        num_records >= min_num_records,
        "record chunking error: we miscalculated the minimum number of records ({} < {})",
        num_records,
        min_num_records,
    );
    // Evenly distribute the plaintext between that many records.
    // There may of course be some leftover that won't distribute evenly.
    let plaintext_per_record = plaintext.len() / num_records;
    let mut extra_plaintext = plaintext.len() % num_records;
    // If the final record is very small, we might not be able to fit
    // the recommended number of plaintext bytes, so redistribute them.
    // (Remember, the final block must contain at least one padding byte).
    if size_of_final_record > 0 && plaintext_per_record > size_of_final_record - 1 {
        extra_plaintext += plaintext_per_record - (size_of_final_record - 1)
    }
    // And now we can iterate!
    Ok(PlaintextRecordIterator {
        plaintext,
        pad_length,
        plaintext_per_record,
        extra_plaintext,
        rs,
        sequence_number: 0,
        num_records,
        total_size,
    })
}