Add a new constant-time is_zero() check for RsaIdentity

There are some places in the protocol where we have an all-zero RSA
identity that does not truly represent a key, but rather represents
an absent or unknown key.  For these, it's better to use
`RsaIdentity::is_zero` instead of manually checking for a set of
zero bytes: it expresses the intent better, and ensures that the
operation is constant-time.

I am deliberately not introducing a more general IsZero trait here,
or implementing is_zero for anything else: This is the only one we
seem to need right now.  We can generalize it later if we have to.
This commit is contained in:
Nick Mathewson 2022-09-20 09:13:31 -04:00
parent 7715b9c8d6
commit 657914f778
3 changed files with 33 additions and 0 deletions

View File

@ -0,0 +1,2 @@
MODIFIED: New is_zero API on RsaIdentity.

View File

@ -159,6 +159,17 @@ impl RsaIdentity {
Ok(()) => Some(RsaIdentity::from(array)),
}
}
/// Return true if this `RsaIdentity` is composed entirely of zero-valued
/// bytes.
///
/// Such all-zero values should not be used internally, since they are not
/// the ID of any valid key. Instead, they are used in some places in the
/// Tor protocols.
pub fn is_zero(&self) -> bool {
// We do a constant-time comparison to avoid side-channels.
self.id.ct_eq(&[0; RSA_ID_LEN]).into()
}
}
impl From<[u8; 20]> for RsaIdentity {

View File

@ -63,6 +63,26 @@ fn test_wrong_hex_rsa_ids() {
assert!(RsaIdentity::from_hex("listen carefully, spider of destiny -FZ").is_none());
}
#[test]
fn test_rsa_is_zero() {
use ll::pk::rsa::RsaIdentity;
assert!(
RsaIdentity::from_hex("0000000000000000000000000000000000000000")
.unwrap()
.is_zero()
);
assert!(
!RsaIdentity::from_hex("000000000000000000000000000000000000000F")
.unwrap()
.is_zero()
);
assert!(
!RsaIdentity::from_hex("F000000000000000000000000000000000000000")
.unwrap()
.is_zero()
);
}
// TODO: Proper tests for RSA keys
#[test]