/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! This module implements the parts of ECE that are currently shared by all //! supported schemes, such as the actual AES-GCM encryption of a single record. //! It can't be used in isolation; you must instead provide a concrete instantiation //! of an ECE encryption scheme by implementing the `EncryptionScheme` trait.
usecrate::{crypto::Cryptographer, error::*}; use byteorder::{BigEndian, ByteOrder};
/// Parameters that control the details of the encryption process. /// /// These are the various configuration knobs that could potentially be /// tweaked when encrypting a given piece of data, packaged together /// in a struct for convenience. /// pub(crate) struct WebPushParams { /// The record size, for chunking the plaintext into multiple records. pub rs: u32, /// The total amount of padding to add to the plaintext before encryption. pub pad_length: usize, /// The salt to use when deriving keys. /// The recommended and default value is `None`, which causes a new random /// salt to be used for every encryption. Specifying a specific salt may /// be useful for testing purposes. pub salt: Option<Vec<u8>>,
}
impl WebPushParams { /// Convenience method for getting an appropriate salt value. /// /// If we have a pre-configured salt then it is returned, transferring ownership /// to ensure it is only used once. If we do not have a pre-configured salt then /// a new random one is generated. pubfn take_or_generate_salt(&mutself, cryptographer: &le='color:red'>dyn Cryptographer) -> Result<Vec<u8>> {
Ok(matchself.salt.take() {
Some(salt) => salt,
None => { letmut salt = [0u8; ECE_SALT_LENGTH];
cryptographer.random_bytes(&mut salt)?;
salt.to_vec()
}
})
}
}
impl Default for WebPushParams { fn default() -> Self { // Random salt, no padding, record size = 4096. Self {
rs: ECE_WEBPUSH_DEFAULT_RS,
pad_length: 0,
salt: None,
}
}
}
impl WebPushParams { /// Create new parameters suitable for use with the given plaintext. /// /// This constructor tries to provide some sensible defaults for using /// ECE to encrypt the given plaintext, including: /// /// * padding it to a multiple of 128 bytes. /// * using a random salt /// pub(crate) fn new_for_plaintext(plaintext: &[u8], min_pad_length: usize) -> Self { // We want (plaintext.len() + pad_length) % BLOCK_SIZE == 0, but need to // accomodate the non-zero minimum padding added by the encryption process. letmut pad_length = ECE_WEBPUSH_DEFAULT_PADDING_BLOCK_SIZE
- (plaintext.len() % ECE_WEBPUSH_DEFAULT_PADDING_BLOCK_SIZE); if pad_length < min_pad_length {
pad_length += ECE_WEBPUSH_DEFAULT_PADDING_BLOCK_SIZE;
}
WebPushParams {
pad_length,
..Default::default()
}
}
}
/// Flag to indicate whether we're encrypting or decrypting. /// Used when deriving keys. /// pub(crate) enum EceMode {
Encrypt,
Decrypt,
}
/// Convenience tuple for "key" and "nonce" pair. /// These are always derived as a pair. /// pub(crate) type KeyAndNonce = (Vec<u8>, Vec<u8>);
/// Generates the AES-GCM IV to use for encrypting a single record. /// /// Each record in ECE is encrypted with a unique IV, that combines a "global" nonce /// for the whole data with with the record's sequence number. /// pub(crate) fn generate_iv_for_record(nonce: &[u8], counter: usize) -> [u8; ECE_NONCE_LENGTH] { letmut iv = [0u8; ECE_NONCE_LENGTH]; let offset = ECE_NONCE_LENGTH - 8;
iv[0..offset].copy_from_slice(&nonce[0..offset]); // Combine the remaining unsigned 64-bit integer with the record sequence // number using XOR. See the "nonce derivation" section of the draft. let mask = BigEndian::read_u64(&nonce[offset..]);
BigEndian::write_u64(&mut iv[offset..], mask ^ (counter as u64));
iv
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.