Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for P-384 #41

Merged
merged 11 commits into from
Apr 2, 2023
54 changes: 23 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ jobs:
RUSTFLAGS: -D warnings -A dead_code -A unused_imports
run: cargo test --no-default-features --features="p256"

- name: Run cargo test with just P384 enabled
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: -D warnings -A dead_code -A unused_imports
run: cargo test --no-default-features --features="p384"

- name: Run cargo test with X25519 and serde impls enabled
env:
CARGO_INCREMENTAL: 0
Expand All @@ -54,6 +60,7 @@ jobs:
CARGO_INCREMENTAL: 0
RUSTFLAGS: -D warnings -A dead_code -A unused_imports
run: cargo test --all-features

- name: Run cargo build with all features
env:
CARGO_INCREMENTAL: 0
Expand All @@ -77,6 +84,22 @@ jobs:
with:
command: fmt
args: --all -- --check

# Enable this once x25519-dalek has another 2.0-pre.X release
#msrv:
# name: Current MSRV is 1.65.0
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# # First run `cargo +nightly -Z minimal-verisons check` in order to get a
# # Cargo.lock with the oldest possible deps
# - uses: dtolnay/rust-toolchain@nightly
# - run: cargo -Z minimal-versions check --all-features
# # Now check that `cargo build` works with respect to the oldest possible
# # deps and the stated MSRV
# - uses: dtolnay/rust-toolchain@1.65.0
# - run: cargo build --all-features

clippy:
runs-on: ubuntu-latest
steps:
Expand All @@ -87,34 +110,3 @@ jobs:
toolchain: stable
components: clippy
- run: cargo clippy --all-features -- -D warnings

codecov:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Run cargo-tarpaulin
uses: actions-rs/tarpaulin@v0.1
env:
CARGO_INCREMENTAL: 0
with:
version: 0.15.0
args: --all-features

- name: Upload to codecov.io
uses: codecov/codecov-action@v1.0.2
with:
token: ${{secrets.CODECOV_TOKEN}}

- name: Archive code coverage results
uses: actions/upload-artifact@v1
with:
name: code-coverage-report
path: cobertura.xml
14 changes: 9 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ categories = ["cryptography", "no-std"]

[features]
# "p256" enables the use of ECDH-NIST-P256 as a KEM
# "p384" enables the use of ECDH-NIST-P384 as a KEM
# "x25519" enables the use of the X25519 as a KEM
default = ["alloc", "p256", "x25519"]
x25519 = ["x25519-dalek"]
x25519 = ["dep:x25519-dalek"]
p384 = ["dep:p384"]
p256 = ["dep:p256"]
# Include serde Serialize/Deserialize impls for all relevant types
serde_impls = ["serde", "generic-array/serde"]
# Include allocating methods like open() and seal()
Expand All @@ -33,7 +36,8 @@ digest = "0.10"
hkdf = "0.12"
hmac = "0.12"
rand_core = { version = "0.6", default-features = false }
p256 = { version = "0.11", default-features = false, features = ["arithmetic", "ecdh" ], optional = true}
p256 = { version = "0.13", default-features = false, features = ["arithmetic", "ecdh"], optional = true}
p384 = { version = "0.13", default-features = false, features = ["arithmetic", "ecdh"], optional = true}
sha2 = { version = "0.10", default-features = false }
serde = { version = "1.0", default-features = false, optional = true }
subtle = { version = "2.4", default-features = false }
Expand All @@ -48,8 +52,8 @@ optional = true
[dev-dependencies]
criterion = { version = "0.4", features = ["html_reports"] }
hex = "0.4"
serde = "1.0"
serde_derive = "1.0"
hex-literal = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rand = { version = "0.8", default-features = false, features = ["getrandom", "std_rng"] }

Expand All @@ -59,7 +63,7 @@ required-features = ["x25519"]

[[example]]
name = "agility"
required-features = ["p256", "x25519"]
required-features = ["p256", "p384", "x25519"]

# Tell docs.rs to build docs with `--all-features` and `--cfg docsrs` (for nightly docs features)
[package.metadata.docs.rs]
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ rust-hpke
[![Version](https://img.shields.io/crates/v/hpke.svg)](https://crates.io/crates/hpke)
[![Docs](https://docs.rs/hpke/badge.svg)](https://docs.rs/hpke)
[![CI](https://github.com/rozbb/rust-hpke/workflows/CI/badge.svg)](https://github.com/rozbb/rust-hpke/actions)
[![Coverage](https://codecov.io/gh/rozbb/rust-hpke/branch/master/graph/badge.svg)](https://codecov.io/gh/rozbb/rust-hpke)

This is an implementation of the [HPKE](https://www.rfc-editor.org/rfc/rfc9180.html) hybrid encryption standard (RFC 9180).

Expand All @@ -30,7 +29,7 @@ Here are all the primitives listed in the spec. The primitives with checked boxe
- [X] DHKEM(Curve25519, HKDF-SHA256)
- [ ] DHKEM(Curve448, HKDF-SHA512)
- [X] DHKEM(P-256, HKDF-SHA256)
- [ ] DHKEM(P-384, HKDF-SHA384)
- [X] DHKEM(P-384, HKDF-SHA384)
- [ ] DHKEM(P-521, HKDF-SHA512)
* KDFs
- [X] HKDF-SHA256
Expand All @@ -48,9 +47,10 @@ Default features flags: `alloc`, `x25519`, `p256`.

Feature flag list:

* `alloc` - Includes allocating methods like `open()` and `seal()`
* `alloc` - Includes allocating methods like `AeadCtxR::open()` and `AeadCtxS::seal()`
* `x25519` - Enables X25519-based KEMs
* `p256` - Enables NIST P-256-based KEMs
* `p384` - Enables NIST P-384-based KEMs
* `serde_impls` - Includes implementations of `serde::Serialize` and `serde::Deserialize` for all `hpke::Serializable` and `hpke::Deserializable` types
* `std` - Includes an implementation of `std::error::Error` for `HpkeError`. Also does what `alloc` does.

Expand All @@ -64,7 +64,7 @@ See the [client-server](examples/client_server.rs) example for an idea of how to
MSRV
----

The current minimum supported Rust version (MSRV) is 1.57.0 (`f1edd0429` 2021-11-29).
The current minimum supported Rust version (MSRV) is 1.65.0 (897e37553 2022-11-02).

Changelog
---------
Expand Down
9 changes: 7 additions & 2 deletions examples/agility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use hpke::{
aead::{Aead, AeadCtxR, AeadCtxS, AeadTag, AesGcm128, AesGcm256, ChaCha20Poly1305},
kdf::{HkdfSha256, HkdfSha384, HkdfSha512, Kdf as KdfTrait},
kem::{DhP256HkdfSha256, Kem as KemTrait, X25519HkdfSha256},
kem::{DhP256HkdfSha256, DhP384HkdfSha384, Kem as KemTrait, X25519HkdfSha256},
setup_receiver, setup_sender, Deserializable, HpkeError, OpModeR, OpModeS, PskBundle,
Serializable,
};
Expand Down Expand Up @@ -308,6 +308,7 @@ fn agile_gen_keypair<R: CryptoRng + RngCore>(kem_alg: KemAlg, csprng: &mut R) ->
match kem_alg {
KemAlg::X25519HkdfSha256 => do_gen_keypair!(X25519HkdfSha256, kem_alg, csprng),
KemAlg::DhP256HkdfSha256 => do_gen_keypair!(DhP256HkdfSha256, kem_alg, csprng),
KemAlg::DhP384HkdfSha384 => do_gen_keypair!(DhP384HkdfSha384, kem_alg, csprng),
_ => unimplemented!(),
}
}
Expand Down Expand Up @@ -678,7 +679,11 @@ fn main() {
AeadAlg::AesGcm256,
AeadAlg::ChaCha20Poly1305,
];
let supported_kem_algs = &[KemAlg::X25519HkdfSha256, KemAlg::DhP256HkdfSha256];
let supported_kem_algs = &[
KemAlg::X25519HkdfSha256,
KemAlg::DhP256HkdfSha256,
KemAlg::DhP384HkdfSha384,
];
let supported_kdf_algs = &[KdfAlg::HkdfSha256, KdfAlg::HkdfSha384, KdfAlg::HkdfSha512];

// For every combination of supported algorithms, test an encryption-decryption round trip
Expand Down
29 changes: 29 additions & 0 deletions src/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,4 +731,33 @@ mod test {
crate::kem::DhP256HkdfSha256
);
}

#[cfg(all(feature = "p384", any(feature = "alloc", feature = "std")))]
mod p384_tests {
use super::*;

test_export_idempotence!(test_export_idempotence_p384, crate::kem::DhP384HkdfSha384);
test_exportonly_panics!(
test_exportonly_panics_p384_seal,
test_exportonly_panics_p384_open,
crate::kem::DhP384HkdfSha384
);
test_overflow!(test_overflow_p384, crate::kem::DhP384HkdfSha384);

test_ctx_correctness!(
test_ctx_correctness_aes128_p384,
AesGcm128,
crate::kem::DhP384HkdfSha384
);
test_ctx_correctness!(
test_ctx_correctness_aes256_p384,
AesGcm256,
crate::kem::DhP384HkdfSha384
);
test_ctx_correctness!(
test_ctx_correctness_chacha_p384,
ChaCha20Poly1305,
crate::kem::DhP384HkdfSha384
);
}
}
17 changes: 12 additions & 5 deletions src/dhkex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::{kdf::Kdf as KdfTrait, util::KemSuiteId, Deserializable, Serializable};

use core::fmt::Debug;

#[cfg(feature = "serde_impls")]
use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};

Expand All @@ -23,14 +25,17 @@ pub trait DhKeyExchange {
/// `Kem::gen_keypair` or `Kem::derive_keypair`
#[cfg(feature = "serde_impls")]
type PublicKey: Clone
+ Debug
+ PartialEq
+ Eq
+ Serializable
+ Deserializable
+ SerdeSerialize
+ for<'a> SerdeDeserialize<'a>;
/// The key exchange's public key type. If you want to generate a keypair, see
/// `Kem::gen_keypair` or `Kem::derive_keypair`
#[cfg(not(feature = "serde_impls"))]
type PublicKey: Clone + Serializable + Deserializable;
type PublicKey: Clone + Debug + PartialEq + Eq + Serializable + Deserializable;

/// The key exchange's private key type. If you want to generate a keypair, see
/// `Kem::gen_keypair` or `Kem::derive_keypair`
Expand Down Expand Up @@ -67,12 +72,14 @@ pub trait DhKeyExchange {
) -> (Self::PrivateKey, Self::PublicKey);
}

#[cfg(feature = "p256")]
#[cfg(any(feature = "p256", feature = "p384"))]
pub(crate) mod ecdh_nistp;
#[cfg(feature = "p256")]
pub use ecdh_nistp::DhP256;
pub use ecdh_nistp::p256::DhP256;
#[cfg(feature = "p384")]
pub use ecdh_nistp::p384::DhP384;

#[cfg(feature = "x25519-dalek")]
#[cfg(feature = "x25519")]
pub(crate) mod x25519;
#[cfg(feature = "x25519-dalek")]
#[cfg(feature = "x25519")]
pub use x25519::X25519;