sequoia_openpgp/packet/seip/v2.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
//! Symmetrically Encrypted Integrity Protected data packets version 2.
//!
//! An encrypted data packet is a container. See [Version 2
//! Symmetrically Encrypted and Integrity Protected Data Packet
//! Format] for details.
//!
//! [Version 2 Symmetrically Encrypted and Integrity Protected Data Packet Format]: https://www.rfc-editor.org/rfc/rfc9580.html#name-version-2-symmetrically-enc
use crate::{
Error,
packet::{
self,
Packet,
SEIP,
},
Result,
types::{
AEADAlgorithm,
SymmetricAlgorithm,
},
};
/// Holds an encrypted data packet.
///
/// An encrypted data packet is a container. See [Version 2
/// Symmetrically Encrypted and Integrity Protected Data Packet
/// Format] for details.
///
/// [Version 2 Symmetrically Encrypted and Integrity Protected Data Packet Format]: https://www.rfc-editor.org/rfc/rfc9580.html#name-version-2-symmetrically-enc
///
/// # A note on equality
///
/// An unprocessed (encrypted) `SEIP2` packet is never considered equal
/// to a processed (decrypted) one. Likewise, a processed (decrypted)
/// packet is never considered equal to a structured (parsed) one.
// IMPORTANT: If you add fields to this struct, you need to explicitly
// IMPORTANT: implement PartialEq, Eq, and Hash.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SEIP2 {
/// CTB packet header fields.
pub(crate) common: packet::Common,
/// Symmetric algorithm.
sym_algo: SymmetricAlgorithm,
/// AEAD algorithm.
aead: AEADAlgorithm,
/// Chunk size.
chunk_size: u64,
/// Salt.
salt: [u8; 32],
/// This is a container packet.
container: packet::Container,
}
assert_send_and_sync!(SEIP2);
impl std::ops::Deref for SEIP2 {
type Target = packet::Container;
fn deref(&self) -> &Self::Target {
&self.container
}
}
impl std::ops::DerefMut for SEIP2 {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.container
}
}
impl SEIP2 {
/// Creates a new SEIP2 packet.
pub fn new(sym_algo: SymmetricAlgorithm,
aead: AEADAlgorithm,
chunk_size: u64,
salt: [u8; 32])
-> Result<Self>
{
if chunk_size.count_ones() != 1 {
return Err(Error::InvalidArgument(
format!("chunk size is not a power of two: {}", chunk_size))
.into());
}
if chunk_size < 64 {
return Err(Error::InvalidArgument(
format!("chunk size is too small: {}", chunk_size))
.into());
}
Ok(SEIP2 {
common: Default::default(),
sym_algo,
aead,
chunk_size,
salt,
container: Default::default(),
})
}
/// Gets the symmetric algorithm.
pub fn symmetric_algo(&self) -> SymmetricAlgorithm {
self.sym_algo
}
/// Sets the symmetric algorithm.
pub fn set_symmetric_algo(&mut self, sym_algo: SymmetricAlgorithm)
-> SymmetricAlgorithm {
std::mem::replace(&mut self.sym_algo, sym_algo)
}
/// Gets the AEAD algorithm.
pub fn aead(&self) -> AEADAlgorithm {
self.aead
}
/// Sets the AEAD algorithm.
pub fn set_aead(&mut self, aead: AEADAlgorithm) -> AEADAlgorithm {
std::mem::replace(&mut self.aead, aead)
}
/// Gets the chunk size.
pub fn chunk_size(&self) -> u64 {
self.chunk_size
}
/// Sets the chunk size.
pub fn set_chunk_size(&mut self, chunk_size: u64) -> Result<()> {
if chunk_size.count_ones() != 1 {
return Err(Error::InvalidArgument(
format!("chunk size is not a power of two: {}", chunk_size))
.into());
}
if chunk_size < 64 {
return Err(Error::InvalidArgument(
format!("chunk size is too small: {}", chunk_size))
.into());
}
self.chunk_size = chunk_size;
Ok(())
}
/// Gets the size of a chunk with a digest.
pub fn chunk_digest_size(&self) -> Result<u64> {
Ok(self.chunk_size + self.aead.digest_size()? as u64)
}
/// Gets the salt.
pub fn salt(&self) -> &[u8; 32] {
&self.salt
}
/// Sets the salt.
pub fn set_salt(&mut self, salt: [u8; 32]) -> [u8; 32] {
std::mem::replace(&mut self.salt, salt)
}
}
impl From<SEIP2> for SEIP {
fn from(p: SEIP2) -> Self {
SEIP::V2(p)
}
}
impl From<SEIP2> for Packet {
fn from(s: SEIP2) -> Self {
Packet::SEIP(s.into())
}
}