Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let implementations choose the tag length #192

Merged
merged 3 commits into from
Jul 21, 2023
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
1 change: 1 addition & 0 deletions crates/api-desc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Patch

- Add `crypto::gcm::tag_length()` function
- Use `*const u8` instead of `*mut u8` for opaque data

## 0.1.3
Expand Down
10 changes: 8 additions & 2 deletions crates/api-desc/src/crypto/gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ pub(crate) fn new() -> Item {
support: usize,
}
},
item! {
/// Returns the supported tag length.
///
/// The tag argument to [`encrypt()`] and [`decrypt()`] must be of that length.
fn tag_length "cgt" {} -> { len: usize }
},
item! {
/// Encrypts and authenticates a clear text with associated data given a key and IV.
fn encrypt "cge" {
Expand Down Expand Up @@ -69,7 +75,7 @@ pub(crate) fn new() -> Item {
/// The cipher text.
cipher: *mut u8,

/// The 16 bytes authentication tag.
/// The authentication tag (see [`super::tag_length()`]).
tag: *mut u8,
} -> {
/// Zero on success, bitwise complement of [`Error`](crate::crypto::Error)
Expand All @@ -92,7 +98,7 @@ pub(crate) fn new() -> Item {
/// The length of the additional authenticated data.
aad_len: usize,

/// The 16 bytes authentication tag.
/// The authentication tag (see [`super::tag_length()`]).
tag: *const u8,

/// The length of the cipher (and clear) text.
Expand Down
3 changes: 2 additions & 1 deletion crates/board/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Major

- Make the tag length configurable for `crypto::aead::Api`
- Change crypto API to mention `Keysize`, `BlockSize`, and `OutputSize`

### Minor
Expand Down Expand Up @@ -59,4 +60,4 @@

## 0.1.0

<!-- Increment to skip CHANGELOG.md test: 8 -->
<!-- Increment to skip CHANGELOG.md test: 9 -->
76 changes: 38 additions & 38 deletions crates/board/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ pub mod ecc;

/// Cryptography interface.
pub trait Api {
type Aes128Ccm: aead::Api<U16, U13, U4>;
type Aes256Gcm: aead::Api<U32, U12, U16>;
type Aes128Ccm: aead::Api<U16, U13, Tag = U4>;
type Aes256Gcm: aead::Api<U32, U12>;

type HmacSha256: Support<bool> + Hmac<KeySize = U64, OutputSize = U32>;
type HmacSha384: Support<bool> + Hmac<KeySize = U128, OutputSize = U48>;
Expand All @@ -45,12 +45,12 @@ pub trait Hmac: KeyInit + Update + FixedOutput + MacMarker {}
impl<T: Default + BlockSizeUser + Update + FixedOutputReset + HashMarker> Hash for T {}
impl<T: KeyInit + Update + FixedOutput + MacMarker> Hmac for T {}

pub struct UnsupportedHash<Block: ArrayLength<u8> + 'static, Output: ArrayLength<u8> + 'static> {
pub struct UnsupportedHash<Block: ArrayLength<u8>, Output: ArrayLength<u8>> {
_never: !,
_block: Block,
_output: Output,
}
pub struct UnsupportedHmac<Key: ArrayLength<u8> + 'static, Output: ArrayLength<u8> + 'static> {
pub struct UnsupportedHmac<Key: ArrayLength<u8>, Output: ArrayLength<u8>> {
_never: !,
_key: Key,
_output: Output,
Expand Down Expand Up @@ -79,11 +79,11 @@ macro_rules! software {
impl<T: Api> Api for UnsupportedCrypto<T> {
software! {
#[cfg(feature = "software-crypto-aes128-ccm")]
type Aes128Ccm = ccm::Ccm<aes::Aes128, U4, U13> | Unsupported;
type Aes128Ccm = ccm::Ccm<aes::Aes128, U4, U13> | aead::Unsupported<U4>;
}
software! {
#[cfg(feature = "software-crypto-aes256-gcm")]
type Aes256Gcm = aes_gcm::Aes256Gcm | Unsupported;
type Aes256Gcm = aes_gcm::Aes256Gcm | aead::Unsupported<U16>;
}

software! {
Expand Down Expand Up @@ -127,31 +127,31 @@ impl Api for Unsupported {

impl<B, O> BlockSizeUser for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
type BlockSize = B;
}

impl<B, O> OutputSizeUser for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
type OutputSize = O;
}

impl<B, O> HashMarker for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
}

impl<B, O> Default for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn default() -> Self {
unreachable!()
Expand All @@ -160,8 +160,8 @@ where

impl<B, O> Update for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn update(&mut self, _: &[u8]) {
unreachable!()
Expand All @@ -170,8 +170,8 @@ where

impl<B, O> FixedOutput for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn finalize_into(self, _: &mut Output<Self>) {
unreachable!()
Expand All @@ -180,8 +180,8 @@ where

impl<B, O> FixedOutputReset for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn finalize_into_reset(&mut self, _: &mut Output<Self>) {
unreachable!()
Expand All @@ -190,8 +190,8 @@ where

impl<B, O> Reset for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn reset(&mut self) {
unreachable!()
Expand All @@ -200,39 +200,39 @@ where

impl<B, O> Support<bool> for UnsupportedHash<B, O>
where
B: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
B: ArrayLength<u8>,
O: ArrayLength<u8>,
{
const SUPPORT: bool = false;
}

impl<K, O> KeySizeUser for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
type KeySize = K;
}

impl<K, O> OutputSizeUser for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
type OutputSize = O;
}

impl<K, O> MacMarker for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
}

impl<K, O> KeyInit for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn new(_: &Key<Self>) -> Self {
unreachable!()
Expand All @@ -241,8 +241,8 @@ where

impl<K, O> Update for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn update(&mut self, _: &[u8]) {
unreachable!()
Expand All @@ -251,8 +251,8 @@ where

impl<K, O> FixedOutput for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
fn finalize_into(self, _: &mut Output<Self>) {
unreachable!()
Expand All @@ -261,8 +261,8 @@ where

impl<K, O> Support<bool> for UnsupportedHmac<K, O>
where
K: ArrayLength<u8> + 'static,
O: ArrayLength<u8> + 'static,
K: ArrayLength<u8>,
O: ArrayLength<u8>,
{
const SUPPORT: bool = false;
}
Expand Down
45 changes: 28 additions & 17 deletions crates/board/src/crypto/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use generic_array::{ArrayLength, GenericArray};
#[cfg(feature = "internal-aead")]
pub use software::*;

use crate::{Error, Support, Unsupported};
use crate::{Error, Support};

#[derive(Copy, Clone)]
pub struct AeadSupport {
Expand All @@ -33,51 +33,61 @@ impl From<AeadSupport> for bool {
}

/// Elliptic-curve cryptography interface.
pub trait Api<Key, Iv, Tag>: Support<AeadSupport>
pub trait Api<Key, Iv>: Support<AeadSupport>
where
Key: ArrayLength<u8>,
Iv: ArrayLength<u8>,
Tag: ArrayLength<u8>,
{
/// The tag length.
type Tag: ArrayLength<u8>;

/// Encrypts and authenticates a clear text with associated data given a key and IV.
///
/// The clear- and cipher-texts must have the same length. If the clear text is omitted, then
/// the cipher text is encrypted in place.
fn encrypt(
key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], clear: Option<&[u8]>, cipher: &mut [u8],
tag: &mut Array<Tag>,
tag: &mut Array<Self::Tag>,
) -> Result<(), Error>;

/// Decrypts and authenticates a cipher text with associated data given a key and IV.
///
/// The cipher- and clear-texts must have the same length. If the cipher text is omitted, then
/// the clear text is decrypted in place.
fn decrypt(
key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], cipher: Option<&[u8]>, tag: &Array<Tag>,
clear: &mut [u8],
key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], cipher: Option<&[u8]>,
tag: &Array<Self::Tag>, clear: &mut [u8],
) -> Result<(), Error>;
}

pub type Array<N> = GenericArray<u8, N>;

impl Support<AeadSupport> for Unsupported {
pub struct Unsupported<Tag: ArrayLength<u8>> {
_never: !,
_tag: Tag,
}

impl<Tag: ArrayLength<u8>> Support<AeadSupport> for Unsupported<Tag> {
const SUPPORT: AeadSupport = AeadSupport { no_copy: false, in_place_no_copy: false };
}

impl<Key, Iv, Tag> Api<Key, Iv, Tag> for Unsupported
impl<Key, Iv, Tag: ArrayLength<u8>> Api<Key, Iv> for Unsupported<Tag>
where
Key: ArrayLength<u8>,
Iv: ArrayLength<u8>,
Tag: ArrayLength<u8>,
{
type Tag = Tag;

fn encrypt(
_: &Array<Key>, _: &Array<Iv>, _: &[u8], _: Option<&[u8]>, _: &mut [u8], _: &mut Array<Tag>,
_: &Array<Key>, _: &Array<Iv>, _: &[u8], _: Option<&[u8]>, _: &mut [u8],
_: &mut Array<Self::Tag>,
) -> Result<(), Error> {
unreachable!()
}

fn decrypt(
_: &Array<Key>, _: &Array<Iv>, _: &[u8], _: Option<&[u8]>, _: &Array<Tag>, _: &mut [u8],
_: &Array<Key>, _: &Array<Iv>, _: &[u8], _: Option<&[u8]>, _: &Array<Self::Tag>,
_: &mut [u8],
) -> Result<(), Error> {
unreachable!()
}
Expand All @@ -94,18 +104,19 @@ mod software {
const SUPPORT: AeadSupport = AeadSupport { no_copy: false, in_place_no_copy: true };
}

impl<Key, Iv, Tag, T> Api<Key, Iv, Tag> for T
impl<Key, Iv, T> Api<Key, Iv> for T
where
T: KeyInit + AeadInPlace,
T: KeySizeUser<KeySize = Key>,
T: AeadCore<NonceSize = Iv, TagSize = Tag>,
T: AeadCore<NonceSize = Iv>,
Key: ArrayLength<u8>,
Iv: ArrayLength<u8>,
Tag: ArrayLength<u8>,
{
type Tag = T::TagSize;

fn encrypt(
key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], clear: Option<&[u8]>, cipher: &mut [u8],
tag: &mut Array<Tag>,
tag: &mut Array<Self::Tag>,
) -> Result<(), Error> {
let aead = T::new(key);
if let Some(clear) = clear {
Expand All @@ -118,8 +129,8 @@ mod software {
}

fn decrypt(
key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], cipher: Option<&[u8]>, tag: &Array<Tag>,
clear: &mut [u8],
key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], cipher: Option<&[u8]>,
tag: &Array<Self::Tag>, clear: &mut [u8],
) -> Result<(), Error> {
let aead = T::new(key);
if let Some(cipher) = cipher {
Expand Down
6 changes: 5 additions & 1 deletion crates/prelude/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog

## 0.2.1-git
## 0.3.0-git

### Major

- Make the AES256-GCM tag variable length

### Minor

Expand Down
2 changes: 1 addition & 1 deletion crates/prelude/Cargo.lock

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

Loading