|  | @@ -1,11 +1,11 @@
 | 
											
												
													
														|  |  /// Functions for performing cryptographic operations on the main data structures.
 |  |  /// Functions for performing cryptographic operations on the main data structures.
 | 
											
												
													
														|  |  mod tpm;
 |  |  mod tpm;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -use crate::{BoxInIoErr, Decompose, IntegrityWrite, SectoredBuf, SECTOR_SZ_DEFAULT};
 |  | 
 | 
											
												
													
														|  | 
 |  | +use crate::{Block, BoxInIoErr, Decompose, HeaderAccess, Trailered, WriteInteg, SECTOR_SZ_DEFAULT};
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  use super::{
 |  |  use super::{
 | 
											
												
													
														|  | -    fmt, io, BigArray, Block, Deserialize, Display, Epoch, Formatter, Hashable, Header, Owned,
 |  | 
 | 
											
												
													
														|  | -    Path, Principal, Read, Sectored, Seek, Serialize, TryCompose, Write, Writecap,
 |  | 
 | 
											
												
													
														|  | 
 |  | +    fmt, io, BigArray, Deserialize, Display, Epoch, Formatter, Hashable, Header, Owned, Path,
 | 
											
												
													
														|  | 
 |  | +    Principal, Read, Sectored, Seek, Serialize, TryCompose, Write, Writecap,
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  use btserde::{self, from_vec, to_vec, write_to};
 |  |  use btserde::{self, from_vec, to_vec, write_to};
 | 
											
										
											
												
													
														|  | @@ -25,7 +25,6 @@ use serde::{
 | 
											
												
													
														|  |      ser::{SerializeStruct, Serializer},
 |  |      ser::{SerializeStruct, Serializer},
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  |  use std::{
 |  |  use std::{
 | 
											
												
													
														|  | -    convert::Infallible,
 |  | 
 | 
											
												
													
														|  |      io::{ErrorKind, SeekFrom},
 |  |      io::{ErrorKind, SeekFrom},
 | 
											
												
													
														|  |      marker::PhantomData,
 |  |      marker::PhantomData,
 | 
											
												
													
														|  |      num::TryFromIntError,
 |  |      num::TryFromIntError,
 | 
											
										
											
												
													
														|  | @@ -191,6 +190,12 @@ impl Default for HashKind {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +impl Default for Hash {
 | 
											
												
													
														|  | 
 |  | +    fn default() -> Self {
 | 
											
												
													
														|  | 
 |  | +        HashKind::default().into()
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  impl HashKind {
 |  |  impl HashKind {
 | 
											
												
													
														|  |      pub const fn len(self) -> usize {
 |  |      pub const fn len(self) -> usize {
 | 
											
												
													
														|  |          match self {
 |  |          match self {
 | 
											
										
											
												
													
														|  | @@ -286,7 +291,7 @@ impl Display for Hash {
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  /// A cryptographic signature.
 |  |  /// A cryptographic signature.
 | 
											
												
													
														|  | -#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
 |  | 
 | 
											
												
													
														|  | 
 |  | +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Default)]
 | 
											
												
													
														|  |  pub struct Signature {
 |  |  pub struct Signature {
 | 
											
												
													
														|  |      kind: Sign,
 |  |      kind: Sign,
 | 
											
												
													
														|  |      data: Vec<u8>,
 |  |      data: Vec<u8>,
 | 
											
										
											
												
													
														|  | @@ -630,6 +635,12 @@ pub enum Sign {
 | 
											
												
													
														|  |      RsaSsaPss(RsaSsaPss),
 |  |      RsaSsaPss(RsaSsaPss),
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +impl Default for Sign {
 | 
											
												
													
														|  | 
 |  | +    fn default() -> Self {
 | 
											
												
													
														|  | 
 |  | +        Self::RSA_PSS_2048_SHA_256
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  impl Scheme for Sign {
 |  |  impl Scheme for Sign {
 | 
											
												
													
														|  |      type Kind = Sign;
 |  |      type Kind = Sign;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -1098,6 +1109,16 @@ pub(crate) trait Encrypter {
 | 
											
												
													
														|  |      fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
 |  |      fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +pub(crate) trait EncrypterExt: Encrypter {
 | 
											
												
													
														|  | 
 |  | +    fn ser_encrypt<T: Serialize>(&self, value: &T) -> Result<Ciphertext<T>> {
 | 
											
												
													
														|  | 
 |  | +        let data = to_vec(value)?;
 | 
											
												
													
														|  | 
 |  | +        let data = self.encrypt(&data)?;
 | 
											
												
													
														|  | 
 |  | +        Ok(Ciphertext::new(data))
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl<T: Encrypter + ?Sized> EncrypterExt for T {}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  pub(crate) trait Decrypter {
 |  |  pub(crate) trait Decrypter {
 | 
											
												
													
														|  |      fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
 |  |      fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -1225,9 +1246,9 @@ pub trait MerkleNode: Default + Serialize + for<'de> Deserialize<'de> {
 | 
											
												
													
														|  |  // need to have different structs to support different kinds of hashes.
 |  |  // need to have different structs to support different kinds of hashes.
 | 
											
												
													
														|  |  /// A struct for storing SHA2 256 hashes in a `MerkleTree`.
 |  |  /// A struct for storing SHA2 256 hashes in a `MerkleTree`.
 | 
											
												
													
														|  |  #[derive(Default, Serialize, Deserialize)]
 |  |  #[derive(Default, Serialize, Deserialize)]
 | 
											
												
													
														|  | -struct Sha2_256(Option<[u8; HashKind::Sha2_256.len()]>);
 |  | 
 | 
											
												
													
														|  | 
 |  | +struct Sha2_256Node(Option<[u8; HashKind::Sha2_256.len()]>);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl Sha2_256 {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl Sha2_256Node {
 | 
											
												
													
														|  |      fn as_slice(&self) -> Option<&[u8]> {
 |  |      fn as_slice(&self) -> Option<&[u8]> {
 | 
											
												
													
														|  |          self.0.as_ref().map(|e| e.as_slice())
 |  |          self.0.as_ref().map(|e| e.as_slice())
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
										
											
												
													
														|  | @@ -1268,13 +1289,13 @@ impl Sha2_256 {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl MerkleNode for Sha2_256 {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl MerkleNode for Sha2_256Node {
 | 
											
												
													
														|  |      const KIND: HashKind = HashKind::Sha2_256;
 |  |      const KIND: HashKind = HashKind::Sha2_256;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      fn new<'a, I: Iterator<Item = &'a [u8]>>(parts: I) -> Result<Self> {
 |  |      fn new<'a, I: Iterator<Item = &'a [u8]>>(parts: I) -> Result<Self> {
 | 
											
												
													
														|  |          let mut array = [0u8; Self::KIND.len()];
 |  |          let mut array = [0u8; Self::KIND.len()];
 | 
											
												
													
														|  |          Self::digest(&mut array, parts)?;
 |  |          Self::digest(&mut array, parts)?;
 | 
											
												
													
														|  | -        Ok(Sha2_256(Some(array)))
 |  | 
 | 
											
												
													
														|  | 
 |  | +        Ok(Sha2_256Node(Some(array)))
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      fn combine<'a, I: Iterator<Item = &'a [u8]>>(
 |  |      fn combine<'a, I: Iterator<Item = &'a [u8]>>(
 | 
											
										
											
												
													
														|  | @@ -1386,6 +1407,24 @@ impl BinTreeIndex {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +trait MerkleTree: Sectored {
 | 
											
												
													
														|  | 
 |  | +    /// Checks that the root node contains the given hash data. If it does then `Ok(())` is
 | 
											
												
													
														|  | 
 |  | +    /// returned. If it doesn't, then `Err(Error::HashCmpFailure)` is returned.
 | 
											
												
													
														|  | 
 |  | +    fn assert_root_contains(&mut self, hash_data: &[u8]) -> Result<()>;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Hashes the given data, adds a new node to the tree with its hash and updates the hashes
 | 
											
												
													
														|  | 
 |  | +    /// of all parent nodes.
 | 
											
												
													
														|  | 
 |  | +    fn write(&mut self, offset: usize, data: &[u8]) -> Result<()>;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Verifies that the given data stored from the given offset into the protected data, has not
 | 
											
												
													
														|  | 
 |  | +    /// been modified.
 | 
											
												
													
														|  | 
 |  | +    fn verify(&self, offset: usize, data: &[u8]) -> Result<()>;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Returns the hash data stored in the root node of the tree. An error is returned if and only
 | 
											
												
													
														|  | 
 |  | +    /// if the tree is empty.
 | 
											
												
													
														|  | 
 |  | +    fn root_hash(&self) -> Result<&[u8]>;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  /// An implementation of a Merkle tree, a tree for storing hashes. This implementation is a binary
 |  |  /// An implementation of a Merkle tree, a tree for storing hashes. This implementation is a binary
 | 
											
												
													
														|  |  /// tree which stores its nodes in a vector to ensure data locality.
 |  |  /// tree which stores its nodes in a vector to ensure data locality.
 | 
											
												
													
														|  |  ///
 |  |  ///
 | 
											
										
											
												
													
														|  | @@ -1395,7 +1434,7 @@ impl BinTreeIndex {
 | 
											
												
													
														|  |  /// Each sector corresponds to an offset into the protected data, and in order to verify that a
 |  |  /// Each sector corresponds to an offset into the protected data, and in order to verify that a
 | 
											
												
													
														|  |  /// sector has not been modified, you must supply the offset of the sector.
 |  |  /// sector has not been modified, you must supply the offset of the sector.
 | 
											
												
													
														|  |  #[derive(Serialize, Deserialize)]
 |  |  #[derive(Serialize, Deserialize)]
 | 
											
												
													
														|  | -pub struct MerkleTree<T> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +pub struct VecMerkleTree<T> {
 | 
											
												
													
														|  |      nodes: Vec<T>,
 |  |      nodes: Vec<T>,
 | 
											
												
													
														|  |      /// The size of the sectors of data that this tree will protect.
 |  |      /// The size of the sectors of data that this tree will protect.
 | 
											
												
													
														|  |      sector_sz: usize,
 |  |      sector_sz: usize,
 | 
											
										
											
												
													
														|  | @@ -1403,7 +1442,7 @@ pub struct MerkleTree<T> {
 | 
											
												
													
														|  |      root_verified: bool,
 |  |      root_verified: bool,
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T> MerkleTree<T> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T> VecMerkleTree<T> {
 | 
											
												
													
														|  |      /// A byte to prefix data being hashed for leaf nodes. It's important that this is different
 |  |      /// A byte to prefix data being hashed for leaf nodes. It's important that this is different
 | 
											
												
													
														|  |      /// from `INTERIOR_PREFIX`.
 |  |      /// from `INTERIOR_PREFIX`.
 | 
											
												
													
														|  |      const LEAF_PREFIX: &'static [u8] = b"Leaf";
 |  |      const LEAF_PREFIX: &'static [u8] = b"Leaf";
 | 
											
										
											
												
													
														|  | @@ -1412,8 +1451,8 @@ impl<T> MerkleTree<T> {
 | 
											
												
													
														|  |      const INTERIOR_PREFIX: &'static [u8] = b"Interior";
 |  |      const INTERIOR_PREFIX: &'static [u8] = b"Interior";
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      /// Creates a new tree with no nodes in it and the given sector size.
 |  |      /// Creates a new tree with no nodes in it and the given sector size.
 | 
											
												
													
														|  | -    fn empty(sector_sz: usize) -> MerkleTree<T> {
 |  | 
 | 
											
												
													
														|  | -        MerkleTree {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    fn empty(sector_sz: usize) -> VecMerkleTree<T> {
 | 
											
												
													
														|  | 
 |  | +        VecMerkleTree {
 | 
											
												
													
														|  |              nodes: Vec::new(),
 |  |              nodes: Vec::new(),
 | 
											
												
													
														|  |              sector_sz,
 |  |              sector_sz,
 | 
											
												
													
														|  |              root_verified: true,
 |  |              root_verified: true,
 | 
											
										
											
												
													
														|  | @@ -1478,9 +1517,34 @@ impl<T> MerkleTree<T> {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T: MerkleNode> MerkleTree<T> {
 |  | 
 | 
											
												
													
														|  | -    /// Checks that the root node contains the given hash data. If it does then `Ok(())` is
 |  | 
 | 
											
												
													
														|  | -    /// returned. If it doesn't, then `Err(Error::HashCmpFailure)` is returned.
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T: MerkleNode> VecMerkleTree<T> {
 | 
											
												
													
														|  | 
 |  | +    /// Percolates up the hash change to the given node to the root.
 | 
											
												
													
														|  | 
 |  | +    fn perc_up(&mut self, start: BinTreeIndex) -> Result<()> {
 | 
											
												
													
														|  | 
 |  | +        for index in start.ancestors() {
 | 
											
												
													
														|  | 
 |  | +            self.combine_children(index)?;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        Ok(())
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Combines the hashes of the given node's children and stores it in the given node.
 | 
											
												
													
														|  | 
 |  | +    fn combine_children(&mut self, index: BinTreeIndex) -> Result<()> {
 | 
											
												
													
														|  | 
 |  | +        let left = index.left();
 | 
											
												
													
														|  | 
 |  | +        let right = index.right();
 | 
											
												
													
														|  | 
 |  | +        // Note that index < left && index < right.
 | 
											
												
													
														|  | 
 |  | +        let split = index.0 + 1;
 | 
											
												
													
														|  | 
 |  | +        let (front, back) = self.nodes.split_at_mut(split);
 | 
											
												
													
														|  | 
 |  | +        let dest = &mut front[front.len() - 1];
 | 
											
												
													
														|  | 
 |  | +        let left = back.get(left.0 - split);
 | 
											
												
													
														|  | 
 |  | +        let right = back.get(right.0 - split);
 | 
											
												
													
														|  | 
 |  | +        dest.combine(Self::interior_prefix(), left, right)
 | 
											
												
													
														|  | 
 |  | +            .map_err(|_| Error::IndexOutOfBounds {
 | 
											
												
													
														|  | 
 |  | +                index: index.0,
 | 
											
												
													
														|  | 
 |  | +                limit: Self::len(self.generations() - 1),
 | 
											
												
													
														|  | 
 |  | +            })
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl<T: MerkleNode> MerkleTree for VecMerkleTree<T> {
 | 
											
												
													
														|  |      fn assert_root_contains(&mut self, hash_data: &[u8]) -> Result<()> {
 |  |      fn assert_root_contains(&mut self, hash_data: &[u8]) -> Result<()> {
 | 
											
												
													
														|  |          match self.hash_at(BinTreeIndex(0)) {
 |  |          match self.hash_at(BinTreeIndex(0)) {
 | 
											
												
													
														|  |              Ok(root) => {
 |  |              Ok(root) => {
 | 
											
										
											
												
													
														|  | @@ -1492,8 +1556,6 @@ impl<T: MerkleNode> MerkleTree<T> {
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    /// Hashes the given data, adds a new node to the tree with its hash and updates the hashes
 |  | 
 | 
											
												
													
														|  | -    /// of all parent nodes.
 |  | 
 | 
											
												
													
														|  |      fn write(&mut self, offset: usize, data: &[u8]) -> Result<()> {
 |  |      fn write(&mut self, offset: usize, data: &[u8]) -> Result<()> {
 | 
											
												
													
														|  |          self.assert_sector_sz(data.len())?;
 |  |          self.assert_sector_sz(data.len())?;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -1543,31 +1605,6 @@ impl<T: MerkleNode> MerkleTree<T> {
 | 
											
												
													
														|  |          self.perc_up(index)
 |  |          self.perc_up(index)
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    /// Percolates up the hash change to the given node to the root.
 |  | 
 | 
											
												
													
														|  | -    fn perc_up(&mut self, start: BinTreeIndex) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -        for index in start.ancestors() {
 |  | 
 | 
											
												
													
														|  | -            self.combine_children(index)?;
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -        Ok(())
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    /// Combines the hashes of the given node's children and stores it in the given node.
 |  | 
 | 
											
												
													
														|  | -    fn combine_children(&mut self, index: BinTreeIndex) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -        let left = index.left();
 |  | 
 | 
											
												
													
														|  | -        let right = index.right();
 |  | 
 | 
											
												
													
														|  | -        // Note that index < left && index < right.
 |  | 
 | 
											
												
													
														|  | -        let split = index.0 + 1;
 |  | 
 | 
											
												
													
														|  | -        let (front, back) = self.nodes.split_at_mut(split);
 |  | 
 | 
											
												
													
														|  | -        let dest = &mut front[front.len() - 1];
 |  | 
 | 
											
												
													
														|  | -        let left = back.get(left.0 - split);
 |  | 
 | 
											
												
													
														|  | -        let right = back.get(right.0 - split);
 |  | 
 | 
											
												
													
														|  | -        dest.combine(Self::interior_prefix(), left, right)
 |  | 
 | 
											
												
													
														|  | -            .map_err(|_| Error::IndexOutOfBounds {
 |  | 
 | 
											
												
													
														|  | -                index: index.0,
 |  | 
 | 
											
												
													
														|  | -                limit: Self::len(self.generations() - 1),
 |  | 
 | 
											
												
													
														|  | -            })
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |      /// Verifies that the given data stored from the given offset into the protected data, has not
 |  |      /// Verifies that the given data stored from the given offset into the protected data, has not
 | 
											
												
													
														|  |      /// been modified.
 |  |      /// been modified.
 | 
											
												
													
														|  |      fn verify(&self, offset: usize, data: &[u8]) -> Result<()> {
 |  |      fn verify(&self, offset: usize, data: &[u8]) -> Result<()> {
 | 
											
										
											
												
													
														|  | @@ -1586,88 +1623,182 @@ impl<T: MerkleNode> MerkleTree<T> {
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          Ok(())
 |  |          Ok(())
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn root_hash(&self) -> Result<&[u8]> {
 | 
											
												
													
														|  | 
 |  | +        self.nodes
 | 
											
												
													
														|  | 
 |  | +            .first()
 | 
											
												
													
														|  | 
 |  | +            .map(|node| node.try_as_slice())
 | 
											
												
													
														|  | 
 |  | +            .ok_or_else(|| Error::custom("the tree is empty"))?
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T> Sectored for MerkleTree<T> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T> Sectored for VecMerkleTree<T> {
 | 
											
												
													
														|  |      fn sector_sz(&self) -> usize {
 |  |      fn sector_sz(&self) -> usize {
 | 
											
												
													
														|  |          self.sector_sz
 |  |          self.sector_sz
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -struct MerkleStream<T, H> {
 |  | 
 | 
											
												
													
														|  | -    inner: T,
 |  | 
 | 
											
												
													
														|  | -    tree: MerkleTree<H>,
 |  | 
 | 
											
												
													
														|  | -    offset: usize,
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T> Default for VecMerkleTree<T> {
 | 
											
												
													
														|  | 
 |  | +    fn default() -> Self {
 | 
											
												
													
														|  | 
 |  | +        Self::empty(SECTOR_SZ_DEFAULT)
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<H> MerkleStream<(), H> {
 |  | 
 | 
											
												
													
														|  | -    fn new(tree: MerkleTree<H>) -> Self {
 |  | 
 | 
											
												
													
														|  | -        MerkleStream {
 |  | 
 | 
											
												
													
														|  | -            inner: (),
 |  | 
 | 
											
												
													
														|  | -            tree,
 |  | 
 | 
											
												
													
														|  | -            offset: 0,
 |  | 
 | 
											
												
													
														|  | 
 |  | +#[derive(Serialize, Deserialize, EnumDiscriminants)]
 | 
											
												
													
														|  | 
 |  | +#[strum_discriminants(name(MerkleTreeKind))]
 | 
											
												
													
														|  | 
 |  | +enum VariantMerkleTree {
 | 
											
												
													
														|  | 
 |  | +    Sha2_256(VecMerkleTree<Sha2_256Node>),
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl VariantMerkleTree {
 | 
											
												
													
														|  | 
 |  | +    fn empty(kind: MerkleTreeKind, sector_sz: usize) -> VariantMerkleTree {
 | 
											
												
													
														|  | 
 |  | +        match kind {
 | 
											
												
													
														|  | 
 |  | +            MerkleTreeKind::Sha2_256 => {
 | 
											
												
													
														|  | 
 |  | +                Self::Sha2_256(VecMerkleTree::<Sha2_256Node>::empty(sector_sz))
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T, H> Sectored for MerkleStream<T, H> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl Sectored for VariantMerkleTree {
 | 
											
												
													
														|  | 
 |  | +    fn sector_sz(&self) -> usize {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Self::Sha2_256(tree) => tree.sector_sz(),
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl MerkleTree for VariantMerkleTree {
 | 
											
												
													
														|  | 
 |  | +    fn assert_root_contains(&mut self, hash_data: &[u8]) -> Result<()> {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Self::Sha2_256(tree) => tree.assert_root_contains(hash_data),
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn root_hash(&self) -> Result<&[u8]> {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Self::Sha2_256(tree) => tree.root_hash(),
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn verify(&self, offset: usize, data: &[u8]) -> Result<()> {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Self::Sha2_256(tree) => tree.verify(offset, data),
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn write(&mut self, offset: usize, data: &[u8]) -> Result<()> {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Self::Sha2_256(tree) => tree.write(offset, data),
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl Default for VariantMerkleTree {
 | 
											
												
													
														|  | 
 |  | +    fn default() -> Self {
 | 
											
												
													
														|  | 
 |  | +        Self::Sha2_256(VecMerkleTree::<Sha2_256Node>::default())
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +pub struct MerkleStream<T> {
 | 
											
												
													
														|  | 
 |  | +    trailered: Trailered<T, VariantMerkleTree>,
 | 
											
												
													
														|  | 
 |  | +    tree: VariantMerkleTree,
 | 
											
												
													
														|  | 
 |  | +    pos: usize,
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl<T: Read + Seek> MerkleStream<T> {
 | 
											
												
													
														|  | 
 |  | +    /// Reads a `MerkleTree` from the end of the given stream and returns a stream which uses it.
 | 
											
												
													
														|  | 
 |  | +    pub fn new(inner: T) -> Result<MerkleStream<T>> {
 | 
											
												
													
														|  | 
 |  | +        let (trailered, tree) = Trailered::new(inner)?;
 | 
											
												
													
														|  | 
 |  | +        Ok(MerkleStream {
 | 
											
												
													
														|  | 
 |  | +            trailered,
 | 
											
												
													
														|  | 
 |  | +            tree: tree.unwrap_or_default(),
 | 
											
												
													
														|  | 
 |  | +            pos: 0,
 | 
											
												
													
														|  | 
 |  | +        })
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn with_tree(inner: T, tree: VariantMerkleTree) -> Result<MerkleStream<T>> {
 | 
											
												
													
														|  | 
 |  | +        let (trailered, trailer) = Trailered::new(inner)?;
 | 
											
												
													
														|  | 
 |  | +        if trailer.is_some() {
 | 
											
												
													
														|  | 
 |  | +            return Err(Error::custom(
 | 
											
												
													
														|  | 
 |  | +                "stream already contained a serialized merkle tree",
 | 
											
												
													
														|  | 
 |  | +            ));
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        Ok(MerkleStream {
 | 
											
												
													
														|  | 
 |  | +            trailered,
 | 
											
												
													
														|  | 
 |  | +            tree,
 | 
											
												
													
														|  | 
 |  | +            pos: 0,
 | 
											
												
													
														|  | 
 |  | +        })
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +impl<T> Sectored for MerkleStream<T> {
 | 
											
												
													
														|  |      fn sector_sz(&self) -> usize {
 |  |      fn sector_sz(&self) -> usize {
 | 
											
												
													
														|  |          self.tree.sector_sz()
 |  |          self.tree.sector_sz()
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T, H> TryCompose<T, MerkleStream<T, H>> for MerkleStream<(), H> {
 |  | 
 | 
											
												
													
														|  | -    type Error = Infallible;
 |  | 
 | 
											
												
													
														|  | -    fn try_compose(self, inner: T) -> std::result::Result<MerkleStream<T, H>, Infallible> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T: Read + Seek> TryCompose<T, MerkleStream<T>> for MerkleStream<()> {
 | 
											
												
													
														|  | 
 |  | +    type Error = crate::Error;
 | 
											
												
													
														|  | 
 |  | +    fn try_compose(self, inner: T) -> std::result::Result<MerkleStream<T>, Self::Error> {
 | 
											
												
													
														|  | 
 |  | +        let (trailered, tree) = Trailered::new(inner)?;
 | 
											
												
													
														|  |          Ok(MerkleStream {
 |  |          Ok(MerkleStream {
 | 
											
												
													
														|  | -            inner,
 |  | 
 | 
											
												
													
														|  | -            tree: self.tree,
 |  | 
 | 
											
												
													
														|  | -            offset: self.offset,
 |  | 
 | 
											
												
													
														|  | 
 |  | +            trailered,
 | 
											
												
													
														|  | 
 |  | +            tree: tree.unwrap_or_default(),
 | 
											
												
													
														|  | 
 |  | +            pos: 0,
 | 
											
												
													
														|  |          })
 |  |          })
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T, H> Decompose<T> for MerkleStream<T, H> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T> Decompose<T> for MerkleStream<T> {
 | 
											
												
													
														|  |      fn into_inner(self) -> T {
 |  |      fn into_inner(self) -> T {
 | 
											
												
													
														|  | -        self.inner
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.trailered.inner
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T: IntegrityWrite, H: MerkleNode> Write for MerkleStream<T, H> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T: WriteInteg + Seek> Write for MerkleStream<T> {
 | 
											
												
													
														|  |      fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
 |  |      fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
 | 
											
												
													
														|  |          self.assert_sector_sz(buf.len())?;
 |  |          self.assert_sector_sz(buf.len())?;
 | 
											
												
													
														|  | -        self.tree.write(self.offset, buf)?;
 |  | 
 | 
											
												
													
														|  | -        // Safety: We know the root node exists and is non-empty because we just wrote data into
 |  | 
 | 
											
												
													
														|  | -        // the tree.
 |  | 
 | 
											
												
													
														|  | -        let root = self.tree.nodes.first().unwrap();
 |  | 
 | 
											
												
													
														|  | -        let written = self.inner.integrity_write(buf, root.try_as_slice()?)?;
 |  | 
 | 
											
												
													
														|  | -        self.offset += self.sector_sz();
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.tree.write(self.pos, buf)?;
 | 
											
												
													
														|  | 
 |  | +        let written = self.trailered.write(buf)?;
 | 
											
												
													
														|  | 
 |  | +        self.pos += self.sector_sz();
 | 
											
												
													
														|  |          Ok(written)
 |  |          Ok(written)
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      fn flush(&mut self) -> io::Result<()> {
 |  |      fn flush(&mut self) -> io::Result<()> {
 | 
											
												
													
														|  | -        Ok(())
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let root = self.tree.root_hash()?;
 | 
											
												
													
														|  | 
 |  | +        self.trailered.flush_integ(&self.tree, root)
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T: Read, H: MerkleNode> Read for MerkleStream<T, H> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T: Read + Seek> Read for MerkleStream<T> {
 | 
											
												
													
														|  |      fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
 |  |      fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
 | 
											
												
													
														|  |          self.assert_sector_sz(buf.len())?;
 |  |          self.assert_sector_sz(buf.len())?;
 | 
											
												
													
														|  | -        self.inner.read_exact(buf)?;
 |  | 
 | 
											
												
													
														|  | -        self.tree.verify(self.offset, buf)?;
 |  | 
 | 
											
												
													
														|  | -        self.offset += self.sector_sz();
 |  | 
 | 
											
												
													
														|  | 
 |  | +        self.trailered.read_exact(buf)?;
 | 
											
												
													
														|  | 
 |  | +        self.tree.verify(self.pos, buf)?;
 | 
											
												
													
														|  | 
 |  | +        self.pos += self.sector_sz();
 | 
											
												
													
														|  |          Ok(self.sector_sz())
 |  |          Ok(self.sector_sz())
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -impl<T: Seek, H> Seek for MerkleStream<T, H> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T: Seek> Seek for MerkleStream<T> {
 | 
											
												
													
														|  |      fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
 |  |      fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
 | 
											
												
													
														|  | -        let from_start = self.inner.seek(pos)?;
 |  | 
 | 
											
												
													
														|  | -        self.offset = from_start.try_into().box_err()?;
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let from_start = self.trailered.seek(pos)?;
 | 
											
												
													
														|  | 
 |  | +        self.pos = from_start.try_into().box_err()?;
 | 
											
												
													
														|  |          Ok(from_start)
 |  |          Ok(from_start)
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +impl<T: HeaderAccess> HeaderAccess for MerkleStream<T> {
 | 
											
												
													
														|  | 
 |  | +    fn block_key(&self) -> crate::Result<SymKey> {
 | 
											
												
													
														|  | 
 |  | +        self.trailered.inner.block_key()
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn add_readcap_for(&mut self, owner: Principal, key: &dyn Encrypter) -> crate::Result<()> {
 | 
											
												
													
														|  | 
 |  | +        self.trailered.inner.add_readcap_for(owner, key)
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  // A stream which encrypts all data written to it and decrypts all data read from it.
 |  |  // A stream which encrypts all data written to it and decrypts all data read from it.
 | 
											
												
													
														|  |  pub struct SecretStream<T> {
 |  |  pub struct SecretStream<T> {
 | 
											
												
													
														|  |      inner: T,
 |  |      inner: T,
 | 
											
										
											
												
													
														|  | @@ -1825,37 +1956,25 @@ impl<T: Seek> Seek for SecretStream<T> {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -pub(crate) fn unveil<T: Read + IntegrityWrite + Seek, C: Encrypter + Decrypter, D>(
 |  | 
 | 
											
												
													
														|  | -    block: Block<T, D>,
 |  | 
 | 
											
												
													
														|  | -    principal: &Principal,
 |  | 
 | 
											
												
													
														|  | -    creds: &C,
 |  | 
 | 
											
												
													
														|  | -) -> Result<Block<impl Read + Write + Seek, D>> {
 |  | 
 | 
											
												
													
														|  | -    let readcap = {
 |  | 
 | 
											
												
													
														|  | -        let shared = block.shared.read()?;
 |  | 
 | 
											
												
													
														|  | -        let readcap_ct = shared
 |  | 
 | 
											
												
													
														|  | -            .header
 |  | 
 | 
											
												
													
														|  | -            .readcaps
 |  | 
 | 
											
												
													
														|  | -            .get(principal)
 |  | 
 | 
											
												
													
														|  | -            .ok_or(Error::NoReadCap)?;
 |  | 
 | 
											
												
													
														|  | -        decrypt(readcap_ct, creds)?
 |  | 
 | 
											
												
													
														|  | -    };
 |  | 
 | 
											
												
													
														|  | -    let block = block
 |  | 
 | 
											
												
													
														|  | -        // TODO: The merkle tree needs to be supplied in some other way.
 |  | 
 | 
											
												
													
														|  | -        .compose_body(MerkleStream::new(MerkleTree::<Sha2_256>::empty(
 |  | 
 | 
											
												
													
														|  | -            SECTOR_SZ_DEFAULT,
 |  | 
 | 
											
												
													
														|  | -        )))
 |  | 
 | 
											
												
													
														|  | -        .try_compose_body(SecretStream::new(readcap))?
 |  | 
 | 
											
												
													
														|  | -        .try_compose_body(SectoredBuf::new())?;
 |  | 
 | 
											
												
													
														|  | -    Ok(block)
 |  | 
 | 
											
												
													
														|  | 
 |  | +impl<T: HeaderAccess> HeaderAccess for SecretStream<T> {
 | 
											
												
													
														|  | 
 |  | +    fn block_key(&self) -> crate::Result<SymKey> {
 | 
											
												
													
														|  | 
 |  | +        self.inner.block_key()
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    fn add_readcap_for(&mut self, owner: Principal, key: &dyn Encrypter) -> crate::Result<()> {
 | 
											
												
													
														|  | 
 |  | +        self.inner.add_readcap_for(owner, key)
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +impl<T: Read + Write + Seek + HeaderAccess> Block for SecretStream<T> {}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  pub(crate) fn encrypt<T: Serialize, K: Encrypter>(value: &T, key: &K) -> Result<Ciphertext<T>> {
 |  |  pub(crate) fn encrypt<T: Serialize, K: Encrypter>(value: &T, key: &K) -> Result<Ciphertext<T>> {
 | 
											
												
													
														|  |      let data = to_vec(value)?;
 |  |      let data = to_vec(value)?;
 | 
											
												
													
														|  |      let data = key.encrypt(&data)?;
 |  |      let data = key.encrypt(&data)?;
 | 
											
												
													
														|  |      Ok(Ciphertext::new(data))
 |  |      Ok(Ciphertext::new(data))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -pub(crate) fn decrypt<T: Serialize + DeserializeOwned, K: Decrypter>(
 |  | 
 | 
											
												
													
														|  | 
 |  | +pub(crate) fn decrypt<T: DeserializeOwned, K: Decrypter>(
 | 
											
												
													
														|  |      ciphertext: &Ciphertext<T>,
 |  |      ciphertext: &Ciphertext<T>,
 | 
											
												
													
														|  |      key: &K,
 |  |      key: &K,
 | 
											
												
													
														|  |  ) -> Result<T> {
 |  |  ) -> Result<T> {
 | 
											
										
											
												
													
														|  | @@ -1864,22 +1983,21 @@ pub(crate) fn decrypt<T: Serialize + DeserializeOwned, K: Decrypter>(
 | 
											
												
													
														|  |      Ok(from_vec(&plaintext)?)
 |  |      Ok(from_vec(&plaintext)?)
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -pub(crate) fn sign_block<T, K: Signer, C>(block: &Block<T, C>, priv_key: &K) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -    let mut shared = block.shared.write()?;
 |  | 
 | 
											
												
													
														|  | -    let header = to_vec(&shared.header)?;
 |  | 
 | 
											
												
													
														|  | -    let signature = priv_key.sign(std::iter::once(header.as_slice()))?;
 |  | 
 | 
											
												
													
														|  | -    shared.sig = signature;
 |  | 
 | 
											
												
													
														|  | -    Ok(())
 |  | 
 | 
											
												
													
														|  | 
 |  | +pub(crate) fn sign_header<K: Signer>(header: &Header, signer: &K) -> Result<Signature> {
 | 
											
												
													
														|  | 
 |  | +    let header = to_vec(&header)?;
 | 
											
												
													
														|  | 
 |  | +    signer.sign(std::iter::once(header.as_slice()))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -pub(crate) fn verify_block<T, C>(block: &Block<T, C>) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -    let shared = block.shared.read()?;
 |  | 
 | 
											
												
													
														|  | -    verify_writecap(&shared.header.writecap, &shared.header.path)?;
 |  | 
 | 
											
												
													
														|  | -    let header_data = to_vec(&shared.header)?;
 |  | 
 | 
											
												
													
														|  | -    shared.header.writecap.signing_key.verify(
 |  | 
 | 
											
												
													
														|  | -        std::iter::once(header_data.as_slice()),
 |  | 
 | 
											
												
													
														|  | -        shared.sig.as_slice(),
 |  | 
 | 
											
												
													
														|  | -    )
 |  | 
 | 
											
												
													
														|  | 
 |  | +pub(crate) fn verify_header(header: &Header, sig: &Signature) -> Result<()> {
 | 
											
												
													
														|  | 
 |  | +    let writecap = header
 | 
											
												
													
														|  | 
 |  | +        .writecap
 | 
											
												
													
														|  | 
 |  | +        .as_ref()
 | 
											
												
													
														|  | 
 |  | +        .ok_or(crate::Error::MissingWritecap)?;
 | 
											
												
													
														|  | 
 |  | +    verify_writecap(writecap, &header.path)?;
 | 
											
												
													
														|  | 
 |  | +    let header_data = to_vec(&header)?;
 | 
											
												
													
														|  | 
 |  | +    writecap
 | 
											
												
													
														|  | 
 |  | +        .signing_key
 | 
											
												
													
														|  | 
 |  | +        .verify(std::iter::once(header_data.as_slice()), sig.as_slice())
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  #[derive(Serialize)]
 |  |  #[derive(Serialize)]
 | 
											
										
											
												
													
														|  | @@ -1970,52 +2088,22 @@ pub(crate) fn verify_writecap(mut writecap: &Writecap, path: &Path) -> Result<()
 | 
											
												
													
														|  |      Err(WritecapAuthzErr::ChainTooLong(CHAIN_LEN_LIMIT).into())
 |  |      Err(WritecapAuthzErr::ChainTooLong(CHAIN_LEN_LIMIT).into())
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -pub fn verify_header(_header: &Header, _sig: &Signature) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -    unimplemented!()
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  #[cfg(test)]
 |  |  #[cfg(test)]
 | 
											
												
													
														|  |  mod tests {
 |  |  mod tests {
 | 
											
												
													
														|  |      use super::*;
 |  |      use super::*;
 | 
											
												
													
														|  |      use crate::{test_helpers::*, BrotliParams, SectoredBuf, SECTOR_SZ_DEFAULT};
 |  |      use crate::{test_helpers::*, BrotliParams, SectoredBuf, SECTOR_SZ_DEFAULT};
 | 
											
												
													
														|  |      use std::{io::SeekFrom, time::Duration};
 |  |      use std::{io::SeekFrom, time::Duration};
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    fn encrypt_decrypt_block_test_case<T: Read + IntegrityWrite + Seek, C: Creds, D>(
 |  | 
 | 
											
												
													
														|  | -        mut block: Block<T, D>,
 |  | 
 | 
											
												
													
														|  | -        principal: &Principal,
 |  | 
 | 
											
												
													
														|  | -        creds: &C,
 |  | 
 | 
											
												
													
														|  | -    ) {
 |  | 
 | 
											
												
													
														|  | -        let expected = {
 |  | 
 | 
											
												
													
														|  | -            let mut dest = Vec::new();
 |  | 
 | 
											
												
													
														|  | -            block.seek(SeekFrom::Start(0)).expect("seek failed");
 |  | 
 | 
											
												
													
														|  | -            block
 |  | 
 | 
											
												
													
														|  | -                .body
 |  | 
 | 
											
												
													
														|  | -                .read_to_end(&mut dest)
 |  | 
 | 
											
												
													
														|  | -                .expect("read_to_end failed");
 |  | 
 | 
											
												
													
														|  | -            block.seek(SeekFrom::Start(0)).expect("seek failed");
 |  | 
 | 
											
												
													
														|  | -            dest
 |  | 
 | 
											
												
													
														|  | -        };
 |  | 
 | 
											
												
													
														|  | -        let mut block = unveil(block, principal, creds).expect("unveil failed");
 |  | 
 | 
											
												
													
														|  | -        block.write_all(&expected).expect("write_all failed");
 |  | 
 | 
											
												
													
														|  | -        block.flush().expect("flush failed");
 |  | 
 | 
											
												
													
														|  | -        block.seek(SeekFrom::Start(0)).expect("seek failed");
 |  | 
 | 
											
												
													
														|  | -        let actual = {
 |  | 
 | 
											
												
													
														|  | -            let mut actual = Vec::new();
 |  | 
 | 
											
												
													
														|  | -            block
 |  | 
 | 
											
												
													
														|  | -                .read_to_end(&mut actual)
 |  | 
 | 
											
												
													
														|  | -                .expect("failed to read actual block contents");
 |  | 
 | 
											
												
													
														|  | -            actual
 |  | 
 | 
											
												
													
														|  | -        };
 |  | 
 | 
											
												
													
														|  | -        assert_eq!(expected, actual);
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  |      fn encrypt_decrypt_block() {
 |  |      fn encrypt_decrypt_block() {
 | 
											
												
													
														|  | 
 |  | +        const SECT_SZ: usize = 16;
 | 
											
												
													
														|  | 
 |  | +        const SECT_CT: usize = 8;
 | 
											
												
													
														|  |          let key = make_key_pair();
 |  |          let key = make_key_pair();
 | 
											
												
													
														|  |          let readcap = make_readcap_for(&key);
 |  |          let readcap = make_readcap_for(&key);
 | 
											
												
													
														|  | -        let principal = readcap.issued_to.clone();
 |  | 
 | 
											
												
													
														|  | -        let block = make_block_with(readcap);
 |  | 
 | 
											
												
													
														|  | -        encrypt_decrypt_block_test_case(block, &principal, &key)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let mut block = make_block_with(readcap);
 | 
											
												
													
														|  | 
 |  | +        write_fill(&mut block, SECT_SZ, SECT_CT);
 | 
											
												
													
														|  | 
 |  | +        block.seek(SeekFrom::Start(0)).expect("seek failed");
 | 
											
												
													
														|  | 
 |  | +        read_check(block, SECT_SZ, SECT_CT);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
										
											
												
													
														|  | @@ -2027,18 +2115,6 @@ mod tests {
 | 
											
												
													
														|  |          key.verify([header, message].into_iter(), signature.as_slice())
 |  |          key.verify([header, message].into_iter(), signature.as_slice())
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    #[test]
 |  | 
 | 
											
												
													
														|  | -    fn sign_verify_block_rsa() -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -        let readcap = make_readcap();
 |  | 
 | 
											
												
													
														|  | -        let principal = readcap.issued_to.clone();
 |  | 
 | 
											
												
													
														|  | -        let block = make_block_with(readcap);
 |  | 
 | 
											
												
													
														|  | -        let key = make_key_pair();
 |  | 
 | 
											
												
													
														|  | -        let mut block = unveil(block, &principal, &key).expect("unveil failed");
 |  | 
 | 
											
												
													
														|  | -        sign_block(&mut block, &key)?;
 |  | 
 | 
											
												
													
														|  | -        verify_block(&block)?;
 |  | 
 | 
											
												
													
														|  | -        Ok(())
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  |      fn hash_to_string() {
 |  |      fn hash_to_string() {
 | 
											
												
													
														|  |          let hash = make_principal().0;
 |  |          let hash = make_principal().0;
 | 
											
										
											
												
													
														|  | @@ -2143,8 +2219,8 @@ mod tests {
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  |      fn aeadkey_encrypt_decrypt_aes256gcm() {
 |  |      fn aeadkey_encrypt_decrypt_aes256gcm() {
 | 
											
												
													
														|  |          let key = AeadKey::new(AeadKeyKind::AesGcm256).expect("failed to create key");
 |  |          let key = AeadKey::new(AeadKeyKind::AesGcm256).expect("failed to create key");
 | 
											
												
													
														|  | -        let aad = [0u8; 16];
 |  | 
 | 
											
												
													
														|  | -        let expected = [0u8; 32];
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let aad = [1u8; 16];
 | 
											
												
													
														|  | 
 |  | +        let expected = [2u8; 32];
 | 
											
												
													
														|  |          let tagged = key.encrypt(aad, &expected).expect("encrypt failed");
 |  |          let tagged = key.encrypt(aad, &expected).expect("encrypt failed");
 | 
											
												
													
														|  |          let actual = key.decrypt(&tagged).expect("decrypt failed");
 |  |          let actual = key.decrypt(&tagged).expect("decrypt failed");
 | 
											
												
													
														|  |          assert_eq!(expected, actual.as_slice());
 |  |          assert_eq!(expected, actual.as_slice());
 | 
											
										
											
												
													
														|  | @@ -2153,10 +2229,21 @@ mod tests {
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  |      fn aeadkey_decrypt_fails_when_ct_modified() {
 |  |      fn aeadkey_decrypt_fails_when_ct_modified() {
 | 
											
												
													
														|  |          let key = AeadKey::new(AeadKeyKind::AesGcm256).expect("failed to create key");
 |  |          let key = AeadKey::new(AeadKeyKind::AesGcm256).expect("failed to create key");
 | 
											
												
													
														|  | -        let aad = [0u8; 16];
 |  | 
 | 
											
												
													
														|  | -        let expected = [0u8; 32];
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let aad = [1u8; 16];
 | 
											
												
													
														|  | 
 |  | +        let expected = [2u8; 32];
 | 
											
												
													
														|  |          let mut tagged = key.encrypt(aad, &expected).expect("encrypt failed");
 |  |          let mut tagged = key.encrypt(aad, &expected).expect("encrypt failed");
 | 
											
												
													
														|  | -        tagged.ciphertext.data[0] += 1;
 |  | 
 | 
											
												
													
														|  | 
 |  | +        tagged.ciphertext.data[0] = tagged.ciphertext.data[0].wrapping_add(1);
 | 
											
												
													
														|  | 
 |  | +        let result = key.decrypt(&tagged);
 | 
											
												
													
														|  | 
 |  | +        assert!(result.is_err())
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    #[test]
 | 
											
												
													
														|  | 
 |  | +    fn aeadkey_decrypt_fails_when_aad_modified() {
 | 
											
												
													
														|  | 
 |  | +        let key = AeadKey::new(AeadKeyKind::AesGcm256).expect("failed to create key");
 | 
											
												
													
														|  | 
 |  | +        let aad = [1u8; 16];
 | 
											
												
													
														|  | 
 |  | +        let expected = [2u8; 32];
 | 
											
												
													
														|  | 
 |  | +        let mut tagged = key.encrypt(aad, &expected).expect("encrypt failed");
 | 
											
												
													
														|  | 
 |  | +        tagged.aad[0] = tagged.aad[0].wrapping_add(1);
 | 
											
												
													
														|  |          let result = key.decrypt(&tagged);
 |  |          let result = key.decrypt(&tagged);
 | 
											
												
													
														|  |          assert!(result.is_err())
 |  |          assert!(result.is_err())
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
										
											
												
													
														|  | @@ -2343,8 +2430,10 @@ mod tests {
 | 
											
												
													
														|  |          assert_eq!(63, log2(usize::MAX));
 |  |          assert_eq!(63, log2(usize::MAX));
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    fn make_tree_with<const SZ: usize>(num_sects: usize) -> (MerkleTree<Sha2_256>, Vec<[u8; SZ]>) {
 |  | 
 | 
											
												
													
														|  | -        let mut tree = MerkleTree::<Sha2_256>::empty(SZ);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    fn make_tree_with<const SZ: usize>(
 | 
											
												
													
														|  | 
 |  | +        num_sects: usize,
 | 
											
												
													
														|  | 
 |  | +    ) -> (VecMerkleTree<Sha2_256Node>, Vec<[u8; SZ]>) {
 | 
											
												
													
														|  | 
 |  | +        let mut tree = VecMerkleTree::<Sha2_256Node>::empty(SZ);
 | 
											
												
													
														|  |          let mut sectors = Vec::with_capacity(num_sects);
 |  |          let mut sectors = Vec::with_capacity(num_sects);
 | 
											
												
													
														|  |          for k in 1..(num_sects + 1) {
 |  |          for k in 1..(num_sects + 1) {
 | 
											
												
													
														|  |              let offset = SZ * (k - 1);
 |  |              let offset = SZ * (k - 1);
 | 
											
										
											
												
													
														|  | @@ -2386,7 +2475,7 @@ mod tests {
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  |      fn merkle_tree_data_changed_verify_fails() {
 |  |      fn merkle_tree_data_changed_verify_fails() {
 | 
											
												
													
														|  |          const SZ: usize = SECTOR_SZ_DEFAULT;
 |  |          const SZ: usize = SECTOR_SZ_DEFAULT;
 | 
											
												
													
														|  | -        let mut tree = MerkleTree::<Sha2_256>::empty(SZ);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let mut tree = VecMerkleTree::<Sha2_256Node>::empty(SZ);
 | 
											
												
													
														|  |          let one = [1u8; SZ];
 |  |          let one = [1u8; SZ];
 | 
											
												
													
														|  |          let mut two = [2u8; SZ];
 |  |          let mut two = [2u8; SZ];
 | 
											
												
													
														|  |          let three = [3u8; SZ];
 |  |          let three = [3u8; SZ];
 | 
											
										
											
												
													
														|  | @@ -2405,7 +2494,7 @@ mod tests {
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  |      fn merkle_tree_root_not_verified_verify_fails() {
 |  |      fn merkle_tree_root_not_verified_verify_fails() {
 | 
											
												
													
														|  |          const SZ: usize = SECTOR_SZ_DEFAULT;
 |  |          const SZ: usize = SECTOR_SZ_DEFAULT;
 | 
											
												
													
														|  | -        let mut tree = MerkleTree::<Sha2_256>::empty(SZ);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let mut tree = VecMerkleTree::<Sha2_256Node>::empty(SZ);
 | 
											
												
													
														|  |          let one = [1u8; SZ];
 |  |          let one = [1u8; SZ];
 | 
											
												
													
														|  |          let two = [2u8; SZ];
 |  |          let two = [2u8; SZ];
 | 
											
												
													
														|  |          let three = [3u8; SZ];
 |  |          let three = [3u8; SZ];
 | 
											
										
											
												
													
														|  | @@ -2413,22 +2502,22 @@ mod tests {
 | 
											
												
													
														|  |          tree.write(SZ, &two).expect("append two failed");
 |  |          tree.write(SZ, &two).expect("append two failed");
 | 
											
												
													
														|  |          tree.write(2 * SZ, &three).expect("append three failed");
 |  |          tree.write(2 * SZ, &three).expect("append three failed");
 | 
											
												
													
														|  |          let vec = to_vec(&tree).expect("to_vec failed");
 |  |          let vec = to_vec(&tree).expect("to_vec failed");
 | 
											
												
													
														|  | -        let tree: MerkleTree<Sha2_256> = from_vec(&vec).expect("from_vec failed");
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let tree: VecMerkleTree<Sha2_256Node> = from_vec(&vec).expect("from_vec failed");
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          tree.verify(SZ, &two)
 |  |          tree.verify(SZ, &two)
 | 
											
												
													
														|  |              .expect_err("verify succeeded, though it should have failed");
 |  |              .expect_err("verify succeeded, though it should have failed");
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    fn merkle_stream_sequential_test_case(sect_sz: usize, sect_count: usize) {
 |  | 
 | 
											
												
													
														|  | -        let mut stream = MerkleStream::new(MerkleTree::<Sha2_256>::empty(sect_sz))
 |  | 
 | 
											
												
													
														|  | -            .try_compose(BtCursor::new(vec![0u8; sect_count * sect_sz]))
 |  | 
 | 
											
												
													
														|  | -            .expect("compose failed");
 |  | 
 | 
											
												
													
														|  | -        for k in 1..(sect_count + 1) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    fn merkle_stream_sequential_test_case(sect_sz: usize, sect_ct: usize) {
 | 
											
												
													
														|  | 
 |  | +        let tree = VariantMerkleTree::empty(MerkleTreeKind::Sha2_256, sect_sz);
 | 
											
												
													
														|  | 
 |  | +        let mut stream =
 | 
											
												
													
														|  | 
 |  | +            MerkleStream::with_tree(BtCursor::new(Vec::new()), tree).expect("read from end failed");
 | 
											
												
													
														|  | 
 |  | +        for k in 1..(sect_ct + 1) {
 | 
											
												
													
														|  |              let sector = vec![k as u8; sect_sz];
 |  |              let sector = vec![k as u8; sect_sz];
 | 
											
												
													
														|  |              stream.write(§or).expect("write failed");
 |  |              stream.write(§or).expect("write failed");
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          stream.seek(SeekFrom::Start(0)).expect("seek failed");
 |  |          stream.seek(SeekFrom::Start(0)).expect("seek failed");
 | 
											
												
													
														|  | -        for k in 1..(sect_count + 1) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        for k in 1..(sect_ct + 1) {
 | 
											
												
													
														|  |              let expected = vec![k as u8; sect_sz];
 |  |              let expected = vec![k as u8; sect_sz];
 | 
											
												
													
														|  |              let mut actual = vec![0u8; sect_sz];
 |  |              let mut actual = vec![0u8; sect_sz];
 | 
											
												
													
														|  |              stream.read(&mut actual).expect("read failed");
 |  |              stream.read(&mut actual).expect("read failed");
 | 
											
										
											
												
													
														|  | @@ -2445,10 +2534,23 @@ mod tests {
 | 
											
												
													
														|  |          merkle_stream_sequential_test_case(8192, 20);
 |  |          merkle_stream_sequential_test_case(8192, 20);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    fn make_merkle_stream_filled_with_zeros(
 | 
											
												
													
														|  | 
 |  | +        sect_sz: usize,
 | 
											
												
													
														|  | 
 |  | +        sect_ct: usize,
 | 
											
												
													
														|  | 
 |  | +    ) -> MerkleStream<BtCursor<Vec<u8>>> {
 | 
											
												
													
														|  | 
 |  | +        let tree = VariantMerkleTree::empty(MerkleTreeKind::Sha2_256, sect_sz);
 | 
											
												
													
														|  | 
 |  | +        let mut stream =
 | 
											
												
													
														|  | 
 |  | +            MerkleStream::with_tree(BtCursor::new(Vec::new()), tree).expect("read from end failed");
 | 
											
												
													
														|  | 
 |  | +        let zeros = vec![0u8; sect_sz];
 | 
											
												
													
														|  | 
 |  | +        for _ in 0..sect_ct {
 | 
											
												
													
														|  | 
 |  | +            stream.write(&zeros).expect("write zeros failed");
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        stream.seek(SeekFrom::Start(0)).expect("seek failed");
 | 
											
												
													
														|  | 
 |  | +        stream
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      fn merkle_stream_random_test_case(rando: Randomizer, sect_sz: usize, sect_ct: usize) {
 |  |      fn merkle_stream_random_test_case(rando: Randomizer, sect_sz: usize, sect_ct: usize) {
 | 
											
												
													
														|  | -        let mut stream = MerkleStream::new(MerkleTree::<Sha2_256>::empty(sect_sz))
 |  | 
 | 
											
												
													
														|  | -            .try_compose(BtCursor::new(vec![0u8; sect_sz * sect_ct]))
 |  | 
 | 
											
												
													
														|  | -            .expect("compose failed");
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let mut stream = make_merkle_stream_filled_with_zeros(sect_sz, sect_ct);
 | 
											
												
													
														|  |          let indices: Vec<usize> = rando.take(sect_ct).map(|e| e % sect_ct).collect();
 |  |          let indices: Vec<usize> = rando.take(sect_ct).map(|e| e % sect_ct).collect();
 | 
											
												
													
														|  |          for index in indices.iter().map(|e| *e) {
 |  |          for index in indices.iter().map(|e| *e) {
 | 
											
												
													
														|  |              let offset = sect_sz * index;
 |  |              let offset = sect_sz * index;
 | 
											
										
											
												
													
														|  | @@ -2486,10 +2588,7 @@ mod tests {
 | 
											
												
													
														|  |      fn compose_merkle_and_secret_streams() {
 |  |      fn compose_merkle_and_secret_streams() {
 | 
											
												
													
														|  |          const SECT_SZ: usize = 4096;
 |  |          const SECT_SZ: usize = 4096;
 | 
											
												
													
														|  |          const SECT_CT: usize = 16;
 |  |          const SECT_CT: usize = 16;
 | 
											
												
													
														|  | -        let memory = BtCursor::new([0u8; SECT_SZ * SECT_CT]);
 |  | 
 | 
											
												
													
														|  | -        let merkle = MerkleStream::new(MerkleTree::<Sha2_256>::empty(SECT_SZ))
 |  | 
 | 
											
												
													
														|  | -            .try_compose(memory)
 |  | 
 | 
											
												
													
														|  | -            .expect("compose for merkle failed");
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let merkle = make_merkle_stream_filled_with_zeros(SECT_SZ, SECT_CT);
 | 
											
												
													
														|  |          let key = SymKey::generate(SymKeyKind::Aes256Cbc).expect("key generation failed");
 |  |          let key = SymKey::generate(SymKeyKind::Aes256Cbc).expect("key generation failed");
 | 
											
												
													
														|  |          let mut secret = SecretStream::new(key)
 |  |          let mut secret = SecretStream::new(key)
 | 
											
												
													
														|  |              .try_compose(merkle)
 |  |              .try_compose(merkle)
 |