Skip to content

Commit 0a79c87

Browse files
authored
Extend Cipher types (#330)
* feat: update CipherId CipherMode CipherType * build: use a pre-release ver * style: fmt * feat: add derives for CipherId * fix: make chachapoly valid ciphermode Add chachapoly as valid ciphermode for Authenticated Cipher. * feat: add fn for EcPoint Add a no compress version import fn: `from_binary_no_compress`. It seems current way of detect compression is not always true. * feat: make Hmac clone-able * Revert "feat: make Hmac clone-able" This reverts commit 78af5e2. * fix: naming and type
1 parent 5c2a215 commit 0a79c87

File tree

5 files changed

+96
-26
lines changed

5 files changed

+96
-26
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mbedtls/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "mbedtls"
33
# We jumped from v0.9 to v0.12 because v0.10 and v0.11 were based on mbedtls 3.X, which
44
# we decided not to support.
5-
version = "0.12.0"
5+
version = "0.12.0-alpha.1"
66
authors = ["Jethro Beekman <[email protected]>"]
77
build = "build.rs"
88
edition = "2018"

mbedtls/src/cipher/mod.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ pub enum Authenticated {}
6262
impl Type for Authenticated {
6363
fn is_valid_mode(mode: raw::CipherMode) -> bool {
6464
match mode {
65-
raw::CipherMode::GCM | raw::CipherMode::CCM | raw::CipherMode::KW | raw::CipherMode::KWP => true,
65+
raw::CipherMode::GCM
66+
| raw::CipherMode::CCM
67+
| raw::CipherMode::KW
68+
| raw::CipherMode::KWP
69+
| raw::CipherMode::CHACHAPOLY => true,
6670
_ => false,
6771
}
6872
}
@@ -457,3 +461,31 @@ fn aes_kwp() {
457461
let out_len = cipher.decrypt_auth(&[], &c, &mut p_out, 0).unwrap().0;
458462
assert_eq!(p, &p_out[..out_len]);
459463
}
464+
465+
#[test]
466+
fn aes_gcm() {
467+
let k = [
468+
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x40, 0x41, 0x42, 0x43,
469+
0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
470+
];
471+
let iv = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16];
472+
473+
let ad = [0x03, 0x04, 0x05];
474+
let p = [0x20, 0x21, 0x22, 0x23];
475+
let c = [0x01, 0x08, 0x55, 0x0f];
476+
let t = [0x3f, 0xd9, 0x8e, 0x74];
477+
let mut p_out = [0u8; 4];
478+
let mut c_out = [0u8; 8];
479+
480+
let cipher =
481+
Cipher::<Encryption, Authenticated, Fresh>::new(raw::CipherId::Aes, raw::CipherMode::GCM, (k.len() * 8) as _).unwrap();
482+
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
483+
484+
cipher.encrypt_auth(&ad, &p, &mut c_out, 4).unwrap();
485+
assert_eq!(c, c_out[0..4]);
486+
assert_eq!(t, c_out[4..8]);
487+
let cipher = Cipher::<_, Authenticated, _>::new(raw::CipherId::Aes, raw::CipherMode::GCM, (k.len() * 8) as _).unwrap();
488+
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
489+
cipher.decrypt_auth(&ad, &c_out, &mut p_out, 4).unwrap();
490+
assert_eq!(p, p_out);
491+
}

mbedtls/src/cipher/raw/mod.rs

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ mod serde;
1414

1515
define!(
1616
#[c_ty(cipher_id_t)]
17+
#[derive(Copy, Clone, Eq, PartialEq)]
1718
enum CipherId {
1819
None = CIPHER_ID_NONE,
1920
Null = CIPHER_ID_NULL,
@@ -24,6 +25,7 @@ define!(
2425
Blowfish = CIPHER_ID_BLOWFISH,
2526
Arc4 = CIPHER_ID_ARC4,
2627
Aria = CIPHER_ID_ARIA,
28+
Chacha20 = CIPHER_ID_CHACHA20,
2729
}
2830
);
2931

@@ -39,6 +41,7 @@ impl From<cipher_id_t> for CipherId {
3941
CIPHER_ID_BLOWFISH => CipherId::Blowfish,
4042
CIPHER_ID_ARC4 => CipherId::Arc4,
4143
CIPHER_ID_ARIA => CipherId::Aria,
44+
CIPHER_ID_CHACHA20 => CipherId::Chacha20,
4245
// This should be replaced with TryFrom once it is stable.
4346
_ => panic!("Invalid cipher_id_t"),
4447
}
@@ -58,6 +61,8 @@ define!(
5861
GCM = MODE_GCM,
5962
STREAM = MODE_STREAM,
6063
CCM = MODE_CCM,
64+
XTS = MODE_XTS,
65+
CHACHAPOLY = MODE_CHACHAPOLY,
6166
KW = MODE_KW,
6267
KWP = MODE_KWP,
6368
}
@@ -75,6 +80,8 @@ impl From<cipher_mode_t> for CipherMode {
7580
MODE_GCM => CipherMode::GCM,
7681
MODE_STREAM => CipherMode::STREAM,
7782
MODE_CCM => CipherMode::CCM,
83+
MODE_XTS => CipherMode::XTS,
84+
MODE_CHACHAPOLY => CipherMode::CHACHAPOLY,
7885
MODE_KW => CipherMode::KW,
7986
MODE_KWP => CipherMode::KWP,
8087
// This should be replaced with TryFrom once it is stable.
@@ -135,6 +142,31 @@ define!(
135142
Camellia128Ccm = CIPHER_CAMELLIA_128_CCM,
136143
Camellia192Ccm = CIPHER_CAMELLIA_192_CCM,
137144
Camellia256Ccm = CIPHER_CAMELLIA_256_CCM,
145+
Aria128Ecb = CIPHER_ARIA_128_ECB,
146+
Aria192Ecb = CIPHER_ARIA_192_ECB,
147+
Aria256Ecb = CIPHER_ARIA_256_ECB,
148+
Aria128Cbc = CIPHER_ARIA_128_CBC,
149+
Aria192Cbc = CIPHER_ARIA_192_CBC,
150+
Aria256Cbc = CIPHER_ARIA_256_CBC,
151+
Aria128Cfb128 = CIPHER_ARIA_128_CFB128,
152+
Aria192Cfb128 = CIPHER_ARIA_192_CFB128,
153+
Aria256Cfb128 = CIPHER_ARIA_256_CFB128,
154+
Aria128Ctr = CIPHER_ARIA_128_CTR,
155+
Aria192Ctr = CIPHER_ARIA_192_CTR,
156+
Aria256Ctr = CIPHER_ARIA_256_CTR,
157+
Aria128Gcm = CIPHER_ARIA_128_GCM,
158+
Aria192Gcm = CIPHER_ARIA_192_GCM,
159+
Aria256Gcm = CIPHER_ARIA_256_GCM,
160+
Aria128Ccm = CIPHER_ARIA_128_CCM,
161+
Aria192Ccm = CIPHER_ARIA_192_CCM,
162+
Aria256Ccm = CIPHER_ARIA_256_CCM,
163+
Aes128Ofb = CIPHER_AES_128_OFB,
164+
Aes192Ofb = CIPHER_AES_192_OFB,
165+
Aes256Ofb = CIPHER_AES_256_OFB,
166+
Aes128Xts = CIPHER_AES_128_XTS,
167+
Aes256Xts = CIPHER_AES_256_XTS,
168+
Chacha20 = CIPHER_CHACHA20,
169+
Chacha20Poly1305 = CIPHER_CHACHA20_POLY1305,
138170
Aes128Kw = CIPHER_AES_128_KW,
139171
Aes192Kw = CIPHER_AES_192_KW,
140172
Aes256Kw = CIPHER_AES_256_KW,
@@ -213,41 +245,41 @@ impl Cipher {
213245
unsafe { cipher_update_ad(&mut self.inner, ad.as_ptr(), ad.len()).into_result_discard() }
214246
}
215247

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

224-
if outdata.len() < reqd_size {
256+
if out_data.len() < required_size {
225257
return Err(Error::CipherFullBlockExpected);
226258
}
227259

228260
let mut olen = 0;
229261
unsafe {
230262
cipher_update(
231263
&mut self.inner,
232-
indata.as_ptr(),
233-
indata.len(),
234-
outdata.as_mut_ptr(),
264+
in_data.as_ptr(),
265+
in_data.len(),
266+
out_data.as_mut_ptr(),
235267
&mut olen,
236268
)
237269
.into_result()?;
238270
}
239271
Ok(olen)
240272
}
241273

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

248280
let mut olen = 0;
249281
unsafe {
250-
cipher_finish(&mut self.inner, outdata.as_mut_ptr(), &mut olen).into_result()?;
282+
cipher_finish(&mut self.inner, out_data.as_mut_ptr(), &mut olen).into_result()?;
251283
}
252284
Ok(olen)
253285
}
@@ -274,7 +306,7 @@ impl Cipher {
274306
unsafe { (*self.inner.cipher_info).mode.into() }
275307
}
276308

277-
// Utility function to get mdoe for the selected / setup cipher_info
309+
// Utility function to get mode for the selected / setup cipher_info
278310
pub fn is_authenticated(&self) -> bool {
279311
unsafe {
280312
if (*self.inner.cipher_info).mode == MODE_GCM || (*self.inner.cipher_info).mode == MODE_CCM {
@@ -413,31 +445,31 @@ impl Cipher {
413445
Ok(plain_len)
414446
}
415447

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

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

424456
if unsafe { *self.inner.cipher_info }.mode == MODE_ECB {
425457
// ECB mode requires single-block updates
426-
for chunk in indata.chunks(self.block_size()) {
427-
let len = self.update(chunk, &mut outdata[total_len..])?;
458+
for chunk in in_data.chunks(self.block_size()) {
459+
let len = self.update(chunk, &mut out_data[total_len..])?;
428460
total_len += len;
429461
}
430462
} else {
431-
total_len = self.update(indata, outdata)?;
432-
total_len += self.finish(&mut outdata[total_len..])?;
463+
total_len = self.update(in_data, out_data)?;
464+
total_len += self.finish(&mut out_data[total_len..])?;
433465
}
434466

435467
Ok(total_len)
436468
}
437469

438-
pub fn cmac(&mut self, key: &[u8], data: &[u8], outdata: &mut [u8]) -> Result<()> {
439-
// Check that outdata buffer has enough space
440-
if outdata.len() < self.block_size() {
470+
pub fn cmac(&mut self, key: &[u8], data: &[u8], out_data: &mut [u8]) -> Result<()> {
471+
// Check that out_data buffer has enough space
472+
if out_data.len() < self.block_size() {
441473
return Err(Error::CipherFullBlockExpected);
442474
}
443475
self.reset()?;
@@ -448,7 +480,7 @@ impl Cipher {
448480
(key.len() * 8) as _,
449481
data.as_ptr(),
450482
data.len(),
451-
outdata.as_mut_ptr(),
483+
out_data.as_mut_ptr(),
452484
)
453485
.into_result()?;
454486
}

mbedtls/src/ecp/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,12 @@ impl EcPoint {
283283
}
284284
}
285285

286+
pub fn from_binary_no_compress(group: &EcGroup, bin: &[u8]) -> Result<EcPoint> {
287+
let mut ret = Self::init();
288+
unsafe { ecp_point_read_binary(&group.inner, &mut ret.inner, bin.as_ptr(), bin.len()) }.into_result()?;
289+
Ok(ret)
290+
}
291+
286292
pub fn from_components(x: Mpi, y: Mpi) -> Result<EcPoint> {
287293
let mut ret = Self::init();
288294

0 commit comments

Comments
 (0)