summaryrefslogtreecommitdiffstats
path: root/openpgp/src/packet/seip/v2.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/packet/seip/v2.rs')
-rw-r--r--openpgp/src/packet/seip/v2.rs161
1 files changed, 161 insertions, 0 deletions
diff --git a/openpgp/src/packet/seip/v2.rs b/openpgp/src/packet/seip/v2.rs
new file mode 100644
index 00000000..85d02289
--- /dev/null
+++ b/openpgp/src/packet/seip/v2.rs
@@ -0,0 +1,161 @@
+//! Symmetrically Encrypted Integrity Protected data packets version 2.
+//!
+//! An encrypted data packet is a container. See [XXX] for details.
+
+use crate::{
+ Error,
+ packet::{
+ self,
+ Packet,
+ SEIP,
+ },
+ Result,
+ types::{
+ AEADAlgorithm,
+ SymmetricAlgorithm,
+ },
+};
+
+/// Holds an encrypted data packet.
+///
+/// An encrypted data packet is a container. See [XXX] for details.
+///
+/// # 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())
+ }
+}