Skip to content

Commit fc8eeaf

Browse files
bors[bot]Pagten
andauthored
Merge #124
124: Fixes and improvements in Pk module r=AdrianCX a=Pagten I noticed that the `decrypt()` function would take its return value from uninitialized memory when performing a raw RSA decrypt. Also, the length of the plaintext output buffer was not checked. Edit: Some further changes were incorporated into this PR. The total list of changes is: * Fix returning uninitialized value from `Pk::decrypt()` when using RSA RAW mode * Remove unnecessary use of `MaybeUninit` * Add output buffer length check to `Pk::sign_deterministic()` Co-authored-by: Pieter Agten <[email protected]>
2 parents e849e8f + 35cad59 commit fc8eeaf

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

mbedtls/src/pk/mod.rs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -506,35 +506,39 @@ impl Pk {
506506
plain: &mut [u8],
507507
rng: &mut F,
508508
) -> Result<usize> {
509-
let mut ret = ::core::mem::MaybeUninit::uninit();
510509
if self.pk_type() == Type::Rsa {
511510
let ctx = self.inner.pk_ctx as *mut rsa_context;
512511
if unsafe { (*ctx).padding == RAW_RSA_DECRYPT } {
513-
let ret = unsafe {
512+
let olen = self.len() / 8;
513+
if plain.len() < olen {
514+
return Err(Error::RsaOutputTooLarge);
515+
}
516+
517+
unsafe {
514518
rsa_private(
515519
ctx,
516520
Some(F::call),
517521
rng.data_ptr(),
518522
cipher.as_ptr(),
519523
plain.as_mut_ptr()
520524
).into_result()?;
521-
ret.assume_init()
522525
};
523-
return Ok(ret);
526+
return Ok(olen);
524527
}
525528
}
526-
let ret = unsafe {
529+
530+
let mut ret = 0usize;
531+
unsafe {
527532
pk_decrypt(
528533
&mut self.inner,
529534
cipher.as_ptr(),
530535
cipher.len(),
531536
plain.as_mut_ptr(),
532-
ret.as_mut_ptr(),
537+
&mut ret,
533538
plain.len(),
534539
Some(F::call),
535540
rng.data_ptr(),
536541
).into_result()?;
537-
ret.assume_init()
538542
};
539543
Ok(ret)
540544
}
@@ -581,19 +585,18 @@ impl Pk {
581585
cipher: &mut [u8],
582586
rng: &mut F,
583587
) -> Result<usize> {
584-
let mut ret = ::core::mem::MaybeUninit::uninit();
585-
let ret = unsafe {
588+
let mut ret = 0usize;
589+
unsafe {
586590
pk_encrypt(
587591
&mut self.inner,
588592
plain.as_ptr(),
589593
plain.len(),
590594
cipher.as_mut_ptr(),
591-
ret.as_mut_ptr(),
595+
&mut ret,
592596
cipher.len(),
593597
Some(F::call),
594598
rng.data_ptr(),
595599
).into_result()?;
596-
ret.assume_init()
597600
};
598601
Ok(ret)
599602
}
@@ -666,19 +669,18 @@ impl Pk {
666669
}
667670
_ => return Err(Error::PkSigLenMismatch),
668671
}
669-
let mut ret = ::core::mem::MaybeUninit::uninit();
670-
let ret = unsafe {
672+
let mut ret = 0usize;
673+
unsafe {
671674
pk_sign(
672675
&mut self.inner,
673676
md.into(),
674677
hash.as_ptr(),
675678
hash.len(),
676679
sig.as_mut_ptr(),
677-
ret.as_mut_ptr(),
680+
&mut ret,
678681
Some(F::call),
679682
rng.data_ptr(),
680683
).into_result()?;
681-
ret.assume_init()
682684
};
683685
Ok(ret)
684686
}
@@ -693,8 +695,11 @@ impl Pk {
693695
use crate::rng::RngCallback;
694696

695697
if self.pk_type() == Type::Ecdsa || self.pk_type() == Type::Eckey {
696-
// RFC 6979 signature scheme
698+
if sig.len() < ECDSA_MAX_LEN {
699+
return Err(Error::PkSigLenMismatch);
700+
}
697701

702+
// RFC 6979 signature scheme
698703
let q = EcGroup::new(self.curve()?)?.order()?;
699704
let x = self.ec_private()?;
700705

@@ -703,19 +708,18 @@ impl Pk {
703708

704709
let mut rng = Rfc6979Rng::new(md, &q, &x, hash, &random_seed)?;
705710

706-
let mut ret = ::core::mem::MaybeUninit::uninit();
707-
let ret = unsafe {
711+
let mut ret = 0usize;
712+
unsafe {
708713
pk_sign(
709714
&mut self.inner,
710715
md.into(),
711716
hash.as_ptr(),
712717
hash.len(),
713718
sig.as_mut_ptr(),
714-
ret.as_mut_ptr(),
719+
&mut ret,
715720
Some(Rfc6979Rng::call),
716721
rng.data_ptr(),
717722
).into_result()?;
718-
ret.assume_init()
719723
};
720724
Ok(ret)
721725
} else if self.pk_type() == Type::Rsa {
@@ -1176,13 +1180,14 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi
11761180
cipher.len()
11771181
);
11781182
let mut decrypted_data1 = [0u8; 2048 / 8];
1179-
let length_without_padding = pk.decrypt(&cipher, &mut decrypted_data1, &mut rng).unwrap();
1183+
let length_with_padding = pk.decrypt(&cipher, &mut decrypted_data1, &mut rng).unwrap();
11801184
// set raw decryption padding mode to perform raw decryption
11811185
pk.set_options(Options::Rsa {
11821186
padding: RsaPadding::None
11831187
});
11841188
let mut decrypted_data2 = [0u8; 2048 / 8];
1185-
let length_with_padding = pk.decrypt(&cipher, &mut decrypted_data2, &mut rng).unwrap();
1189+
let length_without_padding = pk.decrypt(&cipher, &mut decrypted_data2, &mut rng).unwrap();
1190+
assert_eq!(length_without_padding, decrypted_data2.len());
11861191
// compare lengths of the decrypted texts
11871192
assert_ne!(length_without_padding, length_with_padding);
11881193
assert_eq!(decrypted_data2.len(), cipher.len());

0 commit comments

Comments
 (0)