Skip to content
This repository has been archived by the owner on Mar 1, 2021. It is now read-only.

Commit

Permalink
Merge pull request #39 from miscreant/upgrade-aes-siv-crate
Browse files Browse the repository at this point in the history
Upgrade `aes-siv` to v0.2; add back `alloc` and `std` features
  • Loading branch information
tarcieri committed Dec 5, 2019
2 parents ea9b1f0 + 35864e0 commit bcb4965
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 63 deletions.
41 changes: 20 additions & 21 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,26 @@ on:
name: Rust

jobs:
# TODO: fix no_std support (see #36)
# build:
# name: Build
# strategy:
# matrix:
# target:
# - thumbv7em-none-eabihf
# - wasm32-unknown-unknown
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v1
# - uses: actions-rs/toolchain@v1
# with:
# toolchain: stable
# override: true
# - name: Install target
# run: rustup target add ${{ matrix.target }}
# - uses: actions-rs/cargo@v1
# with:
# command: build
# args: --no-default-features --lib --target ${{ matrix.target }}
build:
name: Build
strategy:
matrix:
target:
- thumbv7em-none-eabihf
- wasm32-unknown-unknown
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Install target
run: rustup target add ${{ matrix.target }}
- uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --lib --target ${{ matrix.target }}

check:
name: Check
Expand Down
56 changes: 40 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[package]
name = "miscreant"
name = "miscreant"
description = """
Symmetric encryption library providing misuse-resistant
authenticated encryption (MRAE) including AES-SIV (RFC 5297),
AES-PMAC-SIV, and the STREAM segmented encryption construction.
"""
version = "0.4.2" # Also update html_root_url in lib.rs when bumping this
license = "Apache-2.0 OR MIT"
authors = ["Tony Arcieri <bascule@gmail.com>"]
homepage = "https://miscreant.io"
repository = "https://github.com/miscreant/miscreant.rs"
readme = "README.md"
categories = ["cryptography", "no-std"]
keywords = ["aes", "cryptography", "encryption", "security", "streaming"]
edition = "2018"
Symmetric encryption library providing misuse-resistant
authenticated encryption (MRAE) including AES-SIV (RFC 5297),
AES-PMAC-SIV, and the STREAM segmented encryption construction.
"""
version = "0.4.2" # Also update html_root_url in lib.rs when bumping this
license = "Apache-2.0 OR MIT"
authors = ["Tony Arcieri <bascule@gmail.com>"]
homepage = "https://miscreant.io"
repository = "https://github.com/miscreant/miscreant.rs"
readme = "README.md"
categories = ["cryptography", "no-std"]
keywords = ["aes", "cryptography", "encryption", "security", "streaming"]
edition = "2018"

[lib]
crate-type = ["rlib", "staticlib"]
Expand All @@ -23,7 +23,7 @@ travis-ci = { repository = "miscreant/miscreant.rs" }

[dependencies]
aes = { version = "0.3", default-features = false }
aes-siv = { version = "0.1", default-features = false, features = ["alloc"] }
aes-siv = { version = "0.2", default-features = false }
cmac = { version = "0.2", default-features = false }
crypto-mac = { version = "0.7", default-features = false }
ctr = { version = "0.3", default-features = false }
Expand All @@ -35,9 +35,33 @@ subtle-encoding = "0.5"
serde_json = "1"

[features]
default = ["pmac", "stream"]
default = ["std", "pmac", "stream"]
alloc = ["aes-siv/alloc"]
pmac = ["pmac_crate", "aes-siv/pmac"]
std = ["alloc"]
stream = []

[workspace]
members = [".", "benches"]

[profile.dev]
panic = "abort"

[profile.release]
codegen-units = 1
debug = false
debug-assertions = false
lto = false
opt-level = 3
overflow-checks = true
panic = "abort"
rpath = false

[profile.bench]
codegen-units = 1
debug = false
debug-assertions = false
lto = false
opt-level = 3
overflow-checks = false
rpath = false
58 changes: 50 additions & 8 deletions src/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@
//! and authenticity.

use crate::{
generic_array::{typenum::U16, ArrayLength},
generic_array::{typenum::U16, ArrayLength, GenericArray},
Error,
};
use aes::{Aes128, Aes256};
use aes_siv::siv::{Siv, IV_SIZE};
use cmac::Cmac;
use core::ops::Add;
use crypto_mac::Mac;
use ctr::Ctr128;
use pmac_crate::Pmac;
use stream_cipher::{NewStreamCipher, SyncStreamCipher};

#[cfg(feature = "alloc")]
use alloc::vec::Vec;

#[cfg(feature = "pmac")]
use pmac_crate::Pmac;

/// AES-SIV tags (which have a dual role as the synthetic IV)
pub type Tag = GenericArray<u8, U16>;

/// An Authenticated Encryption with Associated Data (AEAD) algorithm.
pub trait Aead {
/// Size of a key associated with this AEAD algorithm
Expand Down Expand Up @@ -71,6 +80,7 @@ pub trait Aead {
) -> Result<&'a [u8], Error>;

/// Encrypt the given plaintext, allocating and returning a Vec<u8> for the ciphertext
#[cfg(feature = "alloc")]
fn encrypt(&mut self, nonce: &[u8], associated_data: &[u8], plaintext: &[u8]) -> Vec<u8> {
let mut buffer = vec![0; IV_SIZE + plaintext.len()];
buffer[IV_SIZE..].copy_from_slice(plaintext);
Expand All @@ -79,6 +89,7 @@ pub trait Aead {
}

/// Decrypt the given ciphertext, allocating and returning a Vec<u8> for the plaintext
#[cfg(feature = "alloc")]
fn decrypt(
&mut self,
nonce: &[u8],
Expand All @@ -103,38 +114,59 @@ where
siv: Siv<C, M>,
}

//
// AES-CMAC-SIV
//

/// SIV AEAD modes based on CMAC
pub type CmacSivAead<BlockCipher> = SivAead<Ctr128<BlockCipher>, Cmac<BlockCipher>>;

/// SIV AEAD modes based on PMAC
pub type PmacSivAead<BlockCipher> = SivAead<Ctr128<BlockCipher>, Pmac<BlockCipher>>;

/// AES-CMAC-SIV in AEAD mode with 256-bit key size (128-bit security)
pub type Aes128SivAead = CmacSivAead<Aes128>;

/// AES-CMAC-SIV in AEAD mode with 512-bit key size (256-bit security)
pub type Aes256SivAead = CmacSivAead<Aes256>;

//
// AES-PMAC-SIV
//

/// SIV AEAD modes based on PMAC
#[cfg(feature = "pmac")]
pub type PmacSivAead<BlockCipher> = SivAead<Ctr128<BlockCipher>, Pmac<BlockCipher>>;

/// AES-PMAC-SIV in AEAD mode with 256-bit key size (128-bit security)
#[cfg(feature = "pmac")]
pub type Aes128PmacSivAead = PmacSivAead<Aes128>;

/// AES-PMAC-SIV in AEAD mode with 512-bit key size (256-bit security)
#[cfg(feature = "pmac")]
pub type Aes256PmacSivAead = PmacSivAead<Aes256>;

impl<C, M> Aead for SivAead<C, M>
where
C: NewStreamCipher<NonceSize = U16> + SyncStreamCipher,
M: Mac<OutputSize = U16>,
C::KeySize: Add,
<C::KeySize as Add>::Output: ArrayLength<u8>,
{
type KeySize = <C as NewStreamCipher>::KeySize;
type TagSize = U16;

fn new(key: &[u8]) -> Self {
Self { siv: Siv::new(key) }
Self {
siv: Siv::new(GenericArray::clone_from_slice(key)),
}
}

fn encrypt_in_place(&mut self, nonce: &[u8], associated_data: &[u8], buffer: &mut [u8]) {
self.siv.encrypt_in_place(&[associated_data, nonce], buffer)
assert!(buffer.len() >= IV_SIZE, "no space for IV in buffer");
let tag = self
.siv
.encrypt_in_place_detached(&[associated_data, nonce], &mut buffer[IV_SIZE..])
.expect("encryption failure!");

buffer[..IV_SIZE].copy_from_slice(&tag);
}

fn decrypt_in_place<'a>(
Expand All @@ -143,6 +175,16 @@ where
associated_data: &[u8],
buffer: &'a mut [u8],
) -> Result<&'a [u8], Error> {
self.siv.decrypt_in_place(&[associated_data, nonce], buffer)
if buffer.len() < IV_SIZE {
return Err(Error);
}

let tag = Tag::clone_from_slice(&buffer[..IV_SIZE]);
self.siv.decrypt_in_place_detached(
&[associated_data, nonce],
&mut buffer[IV_SIZE..],
&tag,
)?;
Ok(&buffer[IV_SIZE..])
}
}
17 changes: 14 additions & 3 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
#![allow(clippy::missing_safety_doc, clippy::too_many_arguments)]

use crate::generic_array::typenum::marker_traits::Unsigned;
use crate::{Aead, Aes128PmacSivAead, Aes128SivAead, Aes256PmacSivAead, Aes256SivAead};
use crate::{Aead, Aes128SivAead, Aes256SivAead};
use core::{ptr, slice};

#[cfg(feature = "pmac")]
use crate::{Aes128PmacSivAead, Aes256PmacSivAead};

//
// AES-128-SIV AEAD
// AES-128-CMAC-SIV AEAD
//

/// AES-128-SIV AEAD: authenticated encryption
Expand Down Expand Up @@ -55,7 +58,7 @@ pub static crypto_aead_aes128siv_KEYBYTES: u32 = 32;
pub static crypto_aead_aes128siv_TAGBYTES: u32 = 16;

//
// AES-256-SIV AEAD
// AES-256-CMAC-SIV AEAD
//

/// AES-256-SIV AEAD: authenticated encryption
Expand Down Expand Up @@ -103,6 +106,7 @@ pub static crypto_aead_aes256siv_TAGBYTES: u32 = 16;
//

/// AES-128-PMAC-SIV AEAD: authenticated encryption
#[cfg(feature = "pmac")]
#[no_mangle]
pub unsafe extern "C" fn crypto_aead_aes128pmacsiv_encrypt(
ct: *mut u8,
Expand All @@ -119,6 +123,7 @@ pub unsafe extern "C" fn crypto_aead_aes128pmacsiv_encrypt(
}

/// AES-128-PMAC-SIV AEAD: authenticated decryption
#[cfg(feature = "pmac")]
#[no_mangle]
pub unsafe extern "C" fn crypto_aead_aes128pmacsiv_decrypt(
msg: *mut u8,
Expand All @@ -135,10 +140,12 @@ pub unsafe extern "C" fn crypto_aead_aes128pmacsiv_decrypt(
}

/// AES-128-PMAC-SIV key size
#[cfg(feature = "pmac")]
#[no_mangle]
pub static crypto_aead_aes128pmacsiv_KEYBYTES: u32 = 32;

/// AES-128-PMAC-SIV authenticator tag size
#[cfg(feature = "pmac")]
#[no_mangle]
pub static crypto_aead_aes128pmacsiv_TAGBYTES: u32 = 16;

Expand All @@ -147,6 +154,7 @@ pub static crypto_aead_aes128pmacsiv_TAGBYTES: u32 = 16;
//

/// AES-256-PMAC-SIV AEAD: authenticated encryption
#[cfg(feature = "pmac")]
#[no_mangle]
pub unsafe extern "C" fn crypto_aead_aes256pmacsiv_encrypt(
ct: *mut u8,
Expand All @@ -163,6 +171,7 @@ pub unsafe extern "C" fn crypto_aead_aes256pmacsiv_encrypt(
}

/// AES-256-PMAC-SIV AEAD: authenticated decryption
#[cfg(feature = "pmac")]
#[no_mangle]
pub unsafe extern "C" fn crypto_aead_aes256pmacsiv_decrypt(
msg: *mut u8,
Expand All @@ -179,10 +188,12 @@ pub unsafe extern "C" fn crypto_aead_aes256pmacsiv_decrypt(
}

/// AES-128-SIV key size
#[cfg(feature = "pmac")]
#[no_mangle]
pub static crypto_aead_aes256pmacsiv_KEYBYTES: u32 = 64;

/// AES-128-SIV authenticator tag size
#[cfg(feature = "pmac")]
#[no_mangle]
pub static crypto_aead_aes256pmacsiv_TAGBYTES: u32 = 16;

Expand Down
26 changes: 22 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//!
//! [AES-NI]: https://en.wikipedia.org/wiki/AES_instruction_set#x86_architecture_processors

#![no_std]
#![doc(html_root_url = "https://docs.rs/miscreant/0.4.2")]
#![warn(
missing_docs,
Expand All @@ -31,14 +32,31 @@
unused_qualifications
)]

#[cfg(feature = "alloc")]
#[macro_use]
extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

mod aead;
pub mod ffi;
#[cfg(feature = "stream")]
pub mod stream;

pub use crate::aead::{Aead, Aes128PmacSivAead, Aes128SivAead, Aes256PmacSivAead, Aes256SivAead};
pub use crate::aead::{Aead, Aes128SivAead, Aes256SivAead};
pub use aes_siv::{
aead::generic_array,
aead::Error,
siv::{Aes128PmacSiv, Aes128Siv, Aes256PmacSiv, Aes256Siv},
aead::{generic_array, Error},
siv::{Aes128Siv, Aes256Siv},
};

#[cfg(feature = "pmac")]
pub use crate::aead::{Aes128PmacSivAead, Aes256PmacSivAead};
#[cfg(feature = "pmac")]
pub use aes_siv::siv::{Aes128PmacSiv, Aes256PmacSiv};

#[cfg(not(any(feature = "std", test)))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}

0 comments on commit bcb4965

Please sign in to comment.