Skip to content

Commit efd9d18

Browse files
committed
refactor(mbedtls): sync with new C mbedtls API
update src - revert unnessary format changes - add `SslStates` - add special case handling in `Read` and `AsyncRead` - update code to sync with new C mbedtls API - some fields become private and renamed with prefix: `private_` - some functions need RNG now: - Pk::from_private_key - Pk::private_from_ec_components - add `mbedtls_psa_external_get_random` update tests - add `hyper_async` test for testing async and hyper14 - update old tests code to sync with new C mbedtls API - revert unnessary format changes
1 parent c7bc4b6 commit efd9d18

38 files changed

+3519
-2600
lines changed

Cargo.lock

Lines changed: 681 additions & 272 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mbedtls/Cargo.toml

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,36 @@ byteorder = { version = "1.0.0", default-features = false }
2525
yasna = { version = "0.2", optional = true, features = ["num-bigint", "bit-vec"] }
2626
num-bigint = { version = "0.2", optional = true }
2727
bit-vec = { version = "0.5", optional = true }
28-
cbc = { version = "0.1.2", optional = true }
29-
rc2 = { version = "0.8.1", optional = true }
3028
cfg-if = "1.0.0"
3129
tokio = { version = "1.16.1", optional = true }
3230

3331
[target.x86_64-fortanix-unknown-sgx.dependencies]
3432
rs-libc = "0.2.0"
3533

3634
[dependencies.mbedtls-sys-auto]
37-
version = "2.26.0"
35+
version = "3.4.0"
3836
default-features = false
3937
features = ["trusted_cert_callback", "threading"]
4038
path = "../mbedtls-sys"
4139

4240
[dependencies.mbedtls-platform-support]
43-
version = "0.1"
41+
version = "0.2"
4442
path = "../mbedtls-platform-support"
4543

4644
[dev-dependencies]
4745
libc = "0.2.0"
4846
rand = "0.4.0"
4947
serde_cbor = "0.6"
5048
hex = "0.3"
51-
matches = "0.1.8"
5249
hyper = { version = "0.10.16", default-features = false }
5350
async-stream = "0.3.0"
5451
futures = "0.3"
5552
tracing = "0.1"
5653
pin-project-lite = "0.2"
54+
rstest = "0.17.0"
55+
rstest_reuse = "0.5.0"
56+
lazy_static = "1.4"
57+
env_logger = "0.10"
5758

5859
[build-dependencies]
5960
cc = "1.0"
@@ -66,17 +67,14 @@ debug = ["mbedtls-sys-auto/debug"]
6667
no_std_deps = ["mbedtls-platform-support/spin", "serde/alloc"]
6768
force_aesni_support = ["mbedtls-platform-support/force_aesni_support", "aesni"]
6869
mpi_force_c_code = ["mbedtls-sys-auto/mpi_force_c_code"]
69-
rdrand = []
70+
rdrand = ["mbedtls-platform-support/rdrand"]
7071
aesni = ["mbedtls-platform-support/aesni"]
71-
zlib = ["mbedtls-sys-auto/zlib"]
7272
time = ["mbedtls-platform-support/time"]
7373
padlock = ["mbedtls-sys-auto/padlock"]
7474
dsa = ["std", "yasna", "num-bigint", "bit-vec"]
75-
pkcs12 = ["std", "yasna"]
76-
pkcs12_rc2 = ["pkcs12", "rc2", "cbc"]
77-
legacy_protocols = ["mbedtls-sys-auto/legacy_protocols"]
7875
async = ["std", "tokio", "tokio/net", "tokio/io-util", "tokio/macros"]
7976
async-rt = ["async", "tokio/rt", "tokio/sync", "tokio/rt-multi-thread"]
77+
tls13 = ["mbedtls-sys-auto/tls13", "mbedtls-platform-support/tls13"]
8078

8179
[[example]]
8280
name = "client"
@@ -110,7 +108,6 @@ required-features = ["std"]
110108
name = "hyper"
111109
required-features = ["std"]
112110

113-
114111
[[test]]
115112
name = "async_session"
116113
path = "tests/async_session.rs"

mbedtls/examples/server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use mbedtls::Result as TlsResult;
2424
mod support;
2525
use support::entropy::entropy_new;
2626
use support::keys;
27+
use support::rand::test_rng;
2728

2829
fn listen<E, F: FnMut(TcpStream) -> Result<(), E>>(mut handle_client: F) -> Result<(), E> {
2930
let sock = TcpListener::bind("127.0.0.1:8080").unwrap();
@@ -39,7 +40,7 @@ fn result_main() -> TlsResult<()> {
3940
let entropy = entropy_new();
4041
let rng = Arc::new(CtrDrbg::new(Arc::new(entropy), None)?);
4142
let cert = Arc::new(Certificate::from_pem_multiple(keys::PEM_CERT.as_bytes())?);
42-
let key = Arc::new(Pk::from_private_key(keys::PEM_KEY.as_bytes(), None)?);
43+
let key = Arc::new(Pk::from_private_key(&mut test_rng(),keys::PEM_KEY.as_bytes(), None)?);
4344
let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default);
4445
config.set_rng(rng);
4546
config.push_cert(cert, key)?;

mbedtls/src/bignum/mod.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,22 +133,15 @@ impl Mpi {
133133
Ok(())
134134
}
135135

136-
fn get_limb(&self, n: usize) -> mpi_uint {
137-
if n < self.inner.n {
138-
unsafe { *self.inner.p.offset(n as isize) }
139-
} else {
140-
// zero pad
141-
0
142-
}
143-
}
144-
145136
pub fn as_u32(&self) -> Result<u32> {
146137
if self.bit_length()? > 32 {
147138
// Not exactly correct but close enough
148139
return Err(codes::MpiBufferTooSmall.into());
149140
}
150141

151-
Ok(self.get_limb(0) as u32)
142+
let mut buf = [0u8; 4];
143+
unsafe { mpi_write_binary(&self.inner, buf.as_mut_ptr(), buf.len()).into_result() }?;
144+
Ok(u32::from_be_bytes(buf))
152145
}
153146

154147
pub fn sign(&self) -> Sign {

mbedtls/src/cipher/mod.rs

Lines changed: 129 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ impl<O: Operation, T: Type> Cipher<O, T, Fresh> {
145145

146146
// Put together the structure to return
147147
Ok(Cipher {
148-
raw_cipher: raw_cipher,
148+
raw_cipher,
149149
padding: raw::CipherPadding::Pkcs7,
150150
_op: PhantomData,
151151
_type: PhantomData,
@@ -273,6 +273,27 @@ impl Cipher<Encryption, TraditionalNoIv, Fresh> {
273273
}
274274

275275
impl Cipher<Encryption, Authenticated, AdditionalData> {
276+
/// The authenticated encryption (AEAD/NIST_KW) function.
277+
///
278+
/// For AEAD modes, the tag will be appended to the ciphertext, as recommended by RFC 5116.
279+
/// (NIST_KW doesn't have a separate tag.)
280+
///
281+
/// # Arguments
282+
///
283+
/// * `ad` - The additional data to authenticate.
284+
/// * `plain` - The plaintext data to be encrypted and authenticated.
285+
/// * `cipher_and_tag` - A mutable reference to a byte array where the ciphertext and authentication tag will be written.
286+
/// * `tag_len` - The length of the tag to be generated.
287+
///
288+
/// # Returns
289+
///
290+
/// * `Result<usize>` - The length of the encrypted data on success.
291+
///
292+
/// # Errors
293+
///
294+
/// * `codes::CipherBadInputData` - For authenticated cipher mode plain_text length should be smaller than cipher length, except
295+
/// AES KW and KWP cipher mode.
296+
/// * Any other errors from underlying `mbedtls_cipher_auth_encrypt_ext` function.
276297
pub fn encrypt_auth(
277298
mut self,
278299
ad: &[u8],
@@ -287,21 +308,58 @@ impl Cipher<Encryption, Authenticated, AdditionalData> {
287308
))
288309
}
289310

311+
/// The authenticated encryption (AEAD/NIST_KW) function.
312+
///
313+
/// For AEAD modes, the tag will be appended to the ciphertext, as recommended by RFC 5116.
314+
/// (NIST_KW doesn't have a separate tag.)
315+
///
316+
/// # Arguments
317+
///
318+
/// * `ad` - The additional data to authenticate
319+
/// * `data_with_tag` - The data to be encrypted and authenticated, along with space for the tag
320+
/// * `tag_len` - The length of the tag to be generated
321+
///
322+
/// # Returns
323+
///
324+
/// * `Result<usize>` - The length of the encrypted data on success
325+
///
326+
/// # Errors
327+
///
328+
/// * `codes::CipherBadInputData` - If the size of `data_with_tag` minus `tag_len` is less than
329+
/// or equal to zero
290330
pub fn encrypt_auth_inplace(
291331
mut self,
292332
ad: &[u8],
293-
data: &mut [u8],
294-
tag: &mut [u8],
333+
data_with_tag: &mut [u8],
334+
tag_len: usize,
295335
) -> Result<(usize, Cipher<Encryption, Authenticated, Finished>)> {
296336
Ok((
297337
self.raw_cipher
298-
.encrypt_auth_inplace(ad, data, tag)?,
338+
.encrypt_auth_inplace(ad, data_with_tag, tag_len)?,
299339
self.change_state(),
300340
))
301341
}
302342
}
303343

304344
impl Cipher<Decryption, Authenticated, AdditionalData> {
345+
/// The authenticated decryption (AEAD/NIST_KW) function.
346+
///
347+
/// # Arguments
348+
///
349+
/// * `ad` - The additional data that was authenticated.
350+
/// * `cipher_and_tag` - The ciphertext and authentication tag that were generated by the corresponding call to `encrypt_auth`.
351+
/// * `plain_text` - A mutable reference to a byte array where the decrypted plaintext will be written.
352+
/// * `tag_len` - The length of the tag.
353+
///
354+
/// # Returns
355+
///
356+
/// * `Result<usize>` - The length of the decrypted data on success.
357+
///
358+
/// # Errors
359+
///
360+
/// * `codes::CipherBadInputData` - For authenticated cipher mode plain_text length should be smaller than cipher length, except
361+
/// AES KW and KWP cipher mode.
362+
/// * Any other errors from underlying `mbedtls_cipher_auth_decrypt_ext` mbedtls function.
305363
pub fn decrypt_auth(
306364
mut self,
307365
ad: &[u8],
@@ -316,15 +374,37 @@ impl Cipher<Decryption, Authenticated, AdditionalData> {
316374
))
317375
}
318376

377+
/// The authenticated decryption (AEAD/NIST_KW) function.
378+
///
379+
/// If the data is not authentic, then the output buffer is zeroed out to
380+
/// prevent the unauthentic plaintext being used, making this interface safer.
381+
///
382+
/// For AEAD modes, the tag must be appended to the ciphertext, as recommended by RFC 5116.
383+
/// (NIST_KW doesn't have a separate tag.)
384+
///
385+
/// # Arguments
386+
///
387+
/// * `ad` - The additional data to authenticate
388+
/// * `data_with_tag` - The data to be decrypted and authenticated, along with space for the tag
389+
/// * `tag_len` - The length of the tag to be generated
390+
///
391+
/// # Returns
392+
///
393+
/// * `Result<usize>` - The length of the decrypted data on success
394+
///
395+
/// # Errors
396+
///
397+
/// * `codes::CipherBadInputData` - If the size of `data_with_tag` minus `tag_len` is less than
398+
/// or equal to zero
319399
pub fn decrypt_auth_inplace(
320400
mut self,
321401
ad: &[u8],
322-
data: &mut [u8],
323-
tag: &[u8],
402+
data_with_tag: &mut [u8],
403+
tag_len: usize,
324404
) -> Result<(usize, Cipher<Decryption, Authenticated, Finished>)> {
325405
Ok((
326406
self.raw_cipher
327-
.decrypt_auth_inplace(ad, data, tag)?,
407+
.decrypt_auth_inplace(ad, data_with_tag, tag_len)?,
328408
self.change_state(),
329409
))
330410
}
@@ -437,6 +517,7 @@ fn ccm_inplace() {
437517
let iv = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16];
438518
let ad = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
439519
let mut c = [0x20, 0x21, 0x22, 0x23, 0x0, 0x0, 0x0, 0x0];
520+
let tag_len: usize = 4;
440521
let validate_cipher = [0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d];
441522
let validate_plain = [0x20, 0x21, 0x22, 0x23];
442523

@@ -447,9 +528,8 @@ fn ccm_inplace() {
447528
)
448529
.unwrap();
449530
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
450-
let (data, tag) = c.split_at_mut(4);
451531
cipher
452-
.encrypt_auth_inplace(&ad, data, tag)
532+
.encrypt_auth_inplace(&ad, &mut c, tag_len)
453533
.unwrap();
454534
assert_eq!(c, validate_cipher);
455535

@@ -460,9 +540,8 @@ fn ccm_inplace() {
460540
)
461541
.unwrap();
462542
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
463-
let (data, tag) = c.split_at_mut(4);
464-
cipher.decrypt_auth_inplace(&ad, data, tag).unwrap();
465-
assert_eq!(validate_plain, data);
543+
cipher.decrypt_auth_inplace(&ad, &mut c, tag_len).unwrap();
544+
assert_eq!(validate_plain, c[..c.len() - tag_len]);
466545
}
467546

468547
#[test]
@@ -504,3 +583,41 @@ fn aes_kwp() {
504583
let out_len = cipher.decrypt_auth(&[], &c, &mut p_out, 0).unwrap().0;
505584
assert_eq!(p, &p_out[..out_len]);
506585
}
586+
587+
#[test]
588+
fn aes_gcm() {
589+
let k = [
590+
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
591+
0x4f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
592+
0x4e, 0x4f,
593+
];
594+
let iv = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16];
595+
596+
let ad = [0x03, 0x04, 0x05];
597+
let p = [0x20, 0x21, 0x22, 0x23];
598+
let c = [0x01, 0x08, 0x55, 0x0f];
599+
let t = [0x3f, 0xd9, 0x8e, 0x74];
600+
let mut p_out = [0u8; 4];
601+
let mut c_out = [0u8; 8];
602+
603+
let cipher = Cipher::<Encryption, Authenticated, Fresh>::new(
604+
raw::CipherId::Aes,
605+
raw::CipherMode::GCM,
606+
(k.len() * 8) as _,
607+
)
608+
.unwrap();
609+
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
610+
611+
cipher.encrypt_auth(&ad, &p, &mut c_out, 4).unwrap();
612+
assert_eq!(c, c_out[0..4]);
613+
assert_eq!(t, c_out[4..8]);
614+
let cipher = Cipher::<_, Authenticated, _>::new(
615+
raw::CipherId::Aes,
616+
raw::CipherMode::GCM,
617+
(k.len() * 8) as _,
618+
)
619+
.unwrap();
620+
let cipher = cipher.set_key_iv(&k, &iv).unwrap();
621+
cipher.decrypt_auth(&ad, &c_out, &mut p_out, 4).unwrap();
622+
assert_eq!(p, p_out);
623+
}

0 commit comments

Comments
 (0)