Skip to content

Commit

Permalink
Improve documentation and add constant time partialeq to keys
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Nov 14, 2023
1 parent 69dccc5 commit 5acb603
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@ sha2 = "0.10.8"
serde_json = { version = "1.0.108", features = ["preserve_order"] }
ureq = { version = "2.8.0", features = ["json"] }
sha1 = "0.10.6"
hex = "0.4.3"
k256 = { version = "0.13.1", features = ["ecdh", "ecdsa", "jwk"] }
p256 = { version = "0.13.2", features = ["ecdh", "ecdsa", "jwk"] }
p384 = { version = "0.13.0", features = ["ecdh", "ecdsa", "jwk"] }
p521 = { version = ">=0.13.3", features = ["ecdh", "ecdsa", "jwk"] }
base64ct = { version = "1.6.0", features = ["alloc"] }
elliptic-curve = { version = "0.13.6", features = ["jwk"] }
primeorder = "0.13.3"
aead = "0.5.2"
concat-kdf = "0.1.0"
ecdsa = "0.16.8"
Expand Down
2 changes: 2 additions & 0 deletions src/jose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,11 @@ pub struct GeneratedKey<const KEYBYTES: usize> {
/// Both this metadata and a connection to the Tang server are needed to regenerate the
/// key for use with encryption. This data can be stored in JSON form.
///
/// <div class="warning">
/// Note that while this data does not contain the encryption key, it should still not
/// be exposed. Any device that can read this metadata could potentially decrypt
/// the ciphertext if it has access to the Tang server.
/// </div>
pub meta: KeyMeta,
}

Expand Down
23 changes: 18 additions & 5 deletions src/key_exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use elliptic_curve::rand_core::OsRng;
use elliptic_curve::sec1::FromEncodedPoint;
use elliptic_curve::sec1::ModulusSize;
use elliptic_curve::sec1::ToEncodedPoint;
use elliptic_curve::subtle::ConstantTimeEq;
use elliptic_curve::zeroize::Zeroizing;
use elliptic_curve::AffinePoint;
use elliptic_curve::Curve;
Expand All @@ -19,17 +20,29 @@ use elliptic_curve::PublicKey;
use elliptic_curve::SecretKey;

/// A zeroizing wrapper around a generated encryption key
#[derive(Clone, Debug, PartialEq)]
pub struct EncryptionKey<const N: usize>(Zeroizing<[u8; N]>);
#[derive(Clone, Debug)]
pub struct EncryptionKey<const KEYBYTES: usize>(Zeroizing<[u8; KEYBYTES]>);

impl<const N: usize> EncryptionKey<N> {
/// Return the secret key
impl<const KEYBYTES: usize> EncryptionKey<KEYBYTES> {
/// Return a reference to the secret key. Treat this data with respect!
#[must_use]
pub fn as_bytes(&self) -> &[u8; N] {
pub fn as_bytes(&self) -> &[u8; KEYBYTES] {
&self.0
}
}

impl<const KEYBYTES: usize> ConstantTimeEq for EncryptionKey<KEYBYTES> {
fn ct_eq(&self, other: &Self) -> elliptic_curve::subtle::Choice {
self.0.ct_eq(other.0.as_ref())
}
}

impl<const KEYBYTES: usize> PartialEq for EncryptionKey<KEYBYTES> {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).into()
}
}

/// Perform key generation in accordance with tang protocol
///
/// Rough description, capitals are public:
Expand Down
37 changes: 37 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
//! A Rust implementation of the Tang portion of Clevis, specified in
//! <https://github.com/latchset/clevis>.
//!
//! ```
//! # #[cfg(not(feature = "_backend"))] fn main() {}
//! # #[cfg(feature = "_backend")]
//! # fn main() {
//! use clevis::{KeyMeta, TangClient};
//!
//! /// 32-byte (256 bit) key
//! const KEY_BYTES: usize = 32;
//!
//! /* key provisioning */
//!
//! let client = TangClient::new("localhost:11697", None);
//!
//! // create a key suitible for encryption (i.e. has gone through a KDF)
//! let out = client.create_secure_key::<KEY_BYTES>().expect("failed to generate key");
//!
//! // use this key to encrypt data
//! let original_key = out.encryption_key;
//!
//! // this must be stored to get the encryption key back for decryption
//! // WARNING: this information should be considered secret, since any device that can
//! // access this and the tang server can retrieve the encryption key. Treat it with
//! // respect!
//! let meta_str = out.meta.to_json();
//!
//! /* key recovery */
//!
//! let new_meta = KeyMeta::from_json(&meta_str).expect("invalid metadata");
//! let new_key = client.recover_secure_key::<KEY_BYTES>(&new_meta).expect("failed to retrieve key");
//!
//! assert_eq!(original_key, new_key);
//! # }
//! ```
#![warn(clippy::pedantic)]
#![allow(clippy::missing_panics_doc)]
#![allow(clippy::missing_errors_doc)]
Expand Down

0 comments on commit 5acb603

Please sign in to comment.