Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/crypto-common.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: crypto-common

on:
pull_request:
paths:
- "crypto-common/**"
- "Cargo.*"
push:
branches: master

defaults:
run:
working-directory: crypto-common

env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-Dwarnings"

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.41.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
- wasm32-unknown-unknown
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
- run: cargo build --no-default-features --release --target ${{ matrix.target }}
test:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.41.0 # MSRV
- stable
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
- run: cargo check --all-features
- run: cargo test
- run: cargo test --features core-api
- run: cargo test --features rand_core
- run: cargo test --features std
- run: cargo test --all-features
10 changes: 5 additions & 5 deletions .github/workflows/crypto-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ jobs:
profile: minimal
toolchain: ${{ matrix.rust }}
- run: cargo check --all-features
- run: cargo test --release
- run: cargo test --features cipher --release
- run: cargo test --features dev --release
- run: cargo test --features std --release
- run: cargo test --all-features --release
- run: cargo test
- run: cargo test --features core-api
- run: cargo test --features dev
- run: cargo test --features std
- run: cargo test --all-features
20 changes: 14 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"aead",
"cipher",
"crypto-common",
"crypto-mac",
"crypto",
"digest",
Expand All @@ -11,3 +12,6 @@ members = [
"signature/async",
"universal-hash",
]

[patch.crates-io]
block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "master" }
3 changes: 2 additions & 1 deletion cipher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ categories = ["cryptography", "no-std"]

[dependencies]
generic-array = "0.14"
crypto-common = { version = "0.1", path = "../crypto-common/" }

blobby = { version = "0.3", optional = true }
rand_core = { version = "0.6", optional = true }

[features]
std = []
std = ["crypto-common/std"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
117 changes: 81 additions & 36 deletions cipher/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,19 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

use crate::errors::InvalidLength;
use core::convert::TryInto;
use crypto_common::FromKey;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

#[cfg(feature = "rand_core")]
use rand_core::{CryptoRng, RngCore};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
/// Key for an algorithm that implements [`FromKey`].
pub type BlockCipherKey<B> = GenericArray<u8, <B as FromKey>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
pub trait NewBlockCipher: Sized {
/// Key size in bytes with which cipher guaranteed to be initialized.
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Ok(Self::new(GenericArray::from_slice(key)))
}
}

/// Generate a random key for this block cipher using the provided [`CryptoRng`].
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
fn generate_key(mut rng: impl CryptoRng + RngCore) -> BlockCipherKey<Self> {
let mut key = BlockCipherKey::<Self>::default();
rng.fill_bytes(&mut key);
key
}
}

/// Trait which marks a type as being a block cipher.
pub trait BlockCipher {
/// Size of the block in bytes
Expand Down Expand Up @@ -209,3 +176,81 @@ impl<Alg: BlockDecrypt> BlockDecrypt for &Alg {
Alg::decrypt_blocks(self, blocks);
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipherNonce {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher_nonce(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

/// Implement [`FromKeyNonce`][crate::FromKeyNonce] for a type which implements [`FromBlockCipherNonce`].
#[macro_export]
macro_rules! impl_from_key_nonce {
($name:ty) => {
impl<C: BlockCipher> crate::FromKeyNonce for $name
where
Self: FromBlockCipherNonce,
<Self as FromBlockCipherNonce>::BlockCipher: FromKey,
{
type KeySize = <<Self as FromBlockCipherNonce>::BlockCipher as FromKey>::KeySize;
type NonceSize = <Self as FromBlockCipherNonce>::NonceSize;

fn new(
key: &GenericArray<u8, Self::KeySize>,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self {
let cipher = <Self as FromBlockCipherNonce>::BlockCipher::new(key);
Self::from_block_cipher_nonce(cipher, nonce)
}

fn new_from_slices(
key: &[u8],
nonce: &[u8],
) -> Result<Self, crate::errors::InvalidLength> {
use crate::errors::InvalidLength;
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
<Self as FromBlockCipherNonce>::BlockCipher::new_from_slice(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher_nonce(cipher, nonce)
})
}
}
}
};
}

/// Implement [`FromKey`] for a type which implements [`From<C>`][From],
/// where `C` implements [`FromKey`].
#[macro_export]
macro_rules! impl_from_key {
($name:ty) => {
impl<C: FromKey> cipher::FromKey for $name
where
Self: From<C>,
{
type KeySize = C::KeySize;

fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
C::new(key).into()
}

fn new_from_slice(key: &[u8]) -> Result<Self, cipher::errors::InvalidLength> {
C::new_from_slice(key)
.map_err(|_| cipher::errors::InvalidLength)
.map(|cipher| cipher.into())
}
}
};
}
94 changes: 0 additions & 94 deletions cipher/src/common.rs

This file was deleted.

Loading