Skip to content

Commit

Permalink
feat: update CipherId CipherMode CipherType
Browse files Browse the repository at this point in the history
  • Loading branch information
Taowyoo committed Oct 26, 2023
1 parent 847011e commit ab09b50
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 27 deletions.
39 changes: 39 additions & 0 deletions mbedtls/src/cipher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,42 @@ fn aes_kwp() {
let out_len = cipher.decrypt_auth(&[], &c, &mut p_out, 0).unwrap().0;
assert_eq!(p, &p_out[..out_len]);
}


#[test]
fn aes_gcm() {
let k = [
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
0x4f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
0x4e, 0x4f,
];
let iv = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16];

let ad = [0x03, 0x04, 0x05];
let p = [0x20, 0x21, 0x22, 0x23];
let c = [0x01, 0x08, 0x55, 0x0f];
let t = [0x3f, 0xd9, 0x8e, 0x74];
let mut p_out = [0u8; 4];
let mut c_out = [0u8; 8];

let cipher = Cipher::<Encryption, Authenticated, Fresh>::new(
raw::CipherId::Aes,
raw::CipherMode::GCM,
(k.len() * 8) as _,
)
.unwrap();
let cipher = cipher.set_key_iv(&k, &iv).unwrap();

cipher.encrypt_auth(&ad, &p, &mut c_out, 4).unwrap();
assert_eq!(c, c_out[0..4]);
assert_eq!(t, c_out[4..8]);
let cipher = Cipher::<_, Authenticated, _>::new(
raw::CipherId::Aes,
raw::CipherMode::GCM,
(k.len() * 8) as _,
)
.unwrap();
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
cipher.decrypt_auth(&ad, &c_out, &mut p_out, 4).unwrap();
assert_eq!(p, p_out);
}
104 changes: 77 additions & 27 deletions mbedtls/src/cipher/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ define!(
Blowfish = CIPHER_ID_BLOWFISH,
Arc4 = CIPHER_ID_ARC4,
Aria = CIPHER_ID_ARIA,
Chacha20 = CIPHER_ID_CHACHA20,
}
);

Expand All @@ -39,6 +40,7 @@ impl From<cipher_id_t> for CipherId {
CIPHER_ID_BLOWFISH => CipherId::Blowfish,
CIPHER_ID_ARC4 => CipherId::Arc4,
CIPHER_ID_ARIA => CipherId::Aria,
CIPHER_ID_CHACHA20 => CipherId::Aria,
// This should be replaced with TryFrom once it is stable.
_ => panic!("Invalid cipher_id_t"),
}
Expand All @@ -58,6 +60,8 @@ define!(
GCM = MODE_GCM,
STREAM = MODE_STREAM,
CCM = MODE_CCM,
XTS = MODE_XTS,
CHACHAPOLY = MODE_CHACHAPOLY,
KW = MODE_KW,
KWP = MODE_KWP,
}
Expand All @@ -75,6 +79,8 @@ impl From<cipher_mode_t> for CipherMode {
MODE_GCM => CipherMode::GCM,
MODE_STREAM => CipherMode::STREAM,
MODE_CCM => CipherMode::CCM,
MODE_XTS => CipherMode::XTS,
MODE_CHACHAPOLY => CipherMode::CHACHAPOLY,
MODE_KW => CipherMode::KW,
MODE_KWP => CipherMode::KWP,
// This should be replaced with TryFrom once it is stable.
Expand Down Expand Up @@ -135,6 +141,31 @@ define!(
Camellia128Ccm = CIPHER_CAMELLIA_128_CCM,
Camellia192Ccm = CIPHER_CAMELLIA_192_CCM,
Camellia256Ccm = CIPHER_CAMELLIA_256_CCM,
CipherAria128Ecb = CIPHER_ARIA_128_ECB,
CipherAria192Ecb = CIPHER_ARIA_192_ECB,
CipherAria256Ecb = CIPHER_ARIA_256_ECB,
CipherAria128Cbc = CIPHER_ARIA_128_CBC,
CipherAria192Cbc = CIPHER_ARIA_192_CBC,
CipherAria256Cbc = CIPHER_ARIA_256_CBC,
CipherAria128Cfb128 = CIPHER_ARIA_128_CFB128,
CipherAria192Cfb128 = CIPHER_ARIA_192_CFB128,
CipherAria256Cfb128 = CIPHER_ARIA_256_CFB128,
CipherAria128Ctr = CIPHER_ARIA_128_CTR,
CipherAria192Ctr = CIPHER_ARIA_192_CTR,
CipherAria256Ctr = CIPHER_ARIA_256_CTR,
CipherAria128Gcm = CIPHER_ARIA_128_GCM,
CipherAria192Gcm = CIPHER_ARIA_192_GCM,
CipherAria256Gcm = CIPHER_ARIA_256_GCM,
CipherAria128Ccm = CIPHER_ARIA_128_CCM,
CipherAria192Ccm = CIPHER_ARIA_192_CCM,
CipherAria256Ccm = CIPHER_ARIA_256_CCM,
CipherAes128Ofb = CIPHER_AES_128_OFB,
CipherAes192Ofb = CIPHER_AES_192_OFB,
CipherAes256Ofb = CIPHER_AES_256_OFB,
CipherAes128Xts = CIPHER_AES_128_XTS,
CipherAes256Xts = CIPHER_AES_256_XTS,
CipherChacha20 = CIPHER_CHACHA20,
CipherChacha20Poly1305 = CIPHER_CHACHA20_POLY1305,
Aes128Kw = CIPHER_AES_128_KW,
Aes192Kw = CIPHER_AES_192_KW,
Aes256Kw = CIPHER_AES_256_KW,
Expand Down Expand Up @@ -213,41 +244,41 @@ impl Cipher {
unsafe { cipher_update_ad(&mut self.inner, ad.as_ptr(), ad.len()).into_result_discard() }
}

pub fn update(&mut self, indata: &[u8], outdata: &mut [u8]) -> Result<usize> {
// Check that minimum required space is available in outdata buffer
let reqd_size = if unsafe { *self.inner.cipher_info }.mode == MODE_ECB {
pub fn update(&mut self, in_data: &[u8], out_data: &mut [u8]) -> Result<usize> {
// Check that minimum required space is available in out_data buffer
let required_size = if unsafe { *self.inner.cipher_info }.mode == MODE_ECB {
self.block_size()
} else {
indata.len() + self.block_size()
in_data.len() + self.block_size()
};

if outdata.len() < reqd_size {
if out_data.len() < required_size {
return Err(Error::CipherFullBlockExpected);
}

let mut olen = 0;
unsafe {
cipher_update(
&mut self.inner,
indata.as_ptr(),
indata.len(),
outdata.as_mut_ptr(),
in_data.as_ptr(),
in_data.len(),
out_data.as_mut_ptr(),
&mut olen,
)
.into_result()?;
}
Ok(olen)
}

pub fn finish(&mut self, outdata: &mut [u8]) -> Result<usize> {
// Check that minimum required space is available in outdata buffer
if outdata.len() < self.block_size() {
pub fn finish(&mut self, out_data: &mut [u8]) -> Result<usize> {
// Check that minimum required space is available in out_data buffer
if out_data.len() < self.block_size() {
return Err(Error::CipherFullBlockExpected);
}

let mut olen = 0;
unsafe {
cipher_finish(&mut self.inner, outdata.as_mut_ptr(), &mut olen).into_result()?;
cipher_finish(&mut self.inner, out_data.as_mut_ptr(), &mut olen).into_result()?;
}
Ok(olen)
}
Expand All @@ -274,7 +305,7 @@ impl Cipher {
unsafe { (*self.inner.cipher_info).mode.into() }
}

// Utility function to get mdoe for the selected / setup cipher_info
// Utility function to get mode for the selected / setup cipher_info
pub fn is_authenticated(&self) -> bool {
unsafe {
if (*self.inner.cipher_info).mode == MODE_GCM || (*self.inner.cipher_info).mode == MODE_CCM {
Expand All @@ -299,7 +330,13 @@ impl Cipher {
self.do_crypto(cipher, plain)
}

pub fn encrypt_auth(&mut self, ad: &[u8], plain: &[u8], cipher_and_tag: &mut [u8], tag_len: usize) -> Result<usize> {
pub fn encrypt_auth(
&mut self,
ad: &[u8],
plain: &[u8],
cipher_and_tag: &mut [u8],
tag_len: usize,
) -> Result<usize> {
if cipher_and_tag
.len()
.checked_sub(tag_len)
Expand Down Expand Up @@ -365,7 +402,12 @@ impl Cipher {
Ok(plain_len)
}

pub fn encrypt_auth_inplace(&mut self, ad: &[u8], data: &mut [u8], tag: &mut [u8]) -> Result<usize> {
pub fn encrypt_auth_inplace(
&mut self,
ad: &[u8],
data: &mut [u8],
tag: &mut [u8],
) -> Result<usize> {
let iv = self.inner.iv;
let iv_len = self.inner.iv_size;
let mut olen = data.len();
Expand All @@ -389,7 +431,12 @@ impl Cipher {
Ok(olen)
}

pub fn decrypt_auth_inplace(&mut self, ad: &[u8], data: &mut [u8], tag: &[u8]) -> Result<usize> {
pub fn decrypt_auth_inplace(
&mut self,
ad: &[u8],
data: &mut [u8],
tag: &[u8],
) -> Result<usize> {
let iv = self.inner.iv;
let iv_len = self.inner.iv_size;
let mut plain_len = data.len();
Expand All @@ -413,31 +460,31 @@ impl Cipher {
Ok(plain_len)
}

fn do_crypto(&mut self, indata: &[u8], outdata: &mut [u8]) -> Result<usize> {
fn do_crypto(&mut self, in_data: &[u8], out_data: &mut [u8]) -> Result<usize> {
self.reset()?;

// The total number of bytes writte to outdata so far. It's safe to
// The total number of bytes written to out_data so far. It's safe to
// use this as a start index for slicing: &slice[slice.len()..] will
// return an empty slice, it doesn't panic.
let mut total_len = 0;

if unsafe { *self.inner.cipher_info }.mode == MODE_ECB {
// ECB mode requires single-block updates
for chunk in indata.chunks(self.block_size()) {
let len = self.update(chunk, &mut outdata[total_len..])?;
for chunk in in_data.chunks(self.block_size()) {
let len = self.update(chunk, &mut out_data[total_len..])?;
total_len += len;
}
} else {
total_len = self.update(indata, outdata)?;
total_len += self.finish(&mut outdata[total_len..])?;
total_len = self.update(in_data, out_data)?;
total_len += self.finish(&mut out_data[total_len..])?;
}

Ok(total_len)
}

pub fn cmac(&mut self, key: &[u8], data: &[u8], outdata: &mut [u8]) -> Result<()> {
// Check that outdata buffer has enough space
if outdata.len() < self.block_size() {
pub fn cmac(&mut self, key: &[u8], data: &[u8], out_data: &mut [u8]) -> Result<()> {
// Check that out_data buffer has enough space
if out_data.len() < self.block_size() {
return Err(Error::CipherFullBlockExpected);
}
self.reset()?;
Expand All @@ -448,7 +495,7 @@ impl Cipher {
(key.len() * 8) as _,
data.as_ptr(),
data.len(),
outdata.as_mut_ptr(),
out_data.as_mut_ptr(),
)
.into_result()?;
}
Expand Down Expand Up @@ -491,5 +538,8 @@ fn cmac_test() {
&mut out,
)
.expect("Success in CMAC");
assert_eq!(&out, b"\x38\x7b\x36\x22\x8b\xa7\x77\x44\x5b\xaf\xa0\x36\x45\xb9\x40\x10");
assert_eq!(
&out,
b"\x38\x7b\x36\x22\x8b\xa7\x77\x44\x5b\xaf\xa0\x36\x45\xb9\x40\x10"
);
}

0 comments on commit ab09b50

Please sign in to comment.