|
@@ -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)
|