Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pkcs11-provider.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
run: |
dnf -y install clang git meson cargo expect pkgconf-pkg-config \
openssl-devel openssl opensc p11-kit-devel gnutls-utils \
gcc g++ sqlite-devel python3-six which
gcc g++ sqlite-devel python3-six which xxd

- name: Checkout Repository
uses: actions/checkout@v6
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/rpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ jobs:
'crate(serial_test/default)' \
'crate(toml)' 'crate(toml/display)' 'crate(toml/parse)' 'crate(toml/serde)' \
'crate(uuid/default)' 'crate(uuid/v4)' 'crate(uuid/v8)' 'crate(cryptoki/default)' \
'crate(vsprintf/default)' 'crate(quick-xml/default)' 'crate(quick-xml/serialize)'
'crate(vsprintf/default)' 'crate(quick-xml/default)' 'crate(quick-xml/serialize)' \
'crate(rustls/custom-provider) = 0.23.37' 'crate(rustls-pemfile/default) >= 2.2.0' \
'crate(rustls/std) >= 0.23.37' 'crate(rustls/tls12) >= 0.23.37'
fi

- name: Checkout Repository
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["ossl", "cdylib", "tools"]
members = ["ossl", "cdylib", "tools", "rustls/ossl"]
default-members = [".", "ossl", "cdylib"]

[workspace.package]
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ check-format:
@find ./ossl -name '*.rs' | xargs rustfmt --check --color auto --edition 2021
@find ./src -name '*.rs' | xargs rustfmt --check --color auto --edition 2021
@find ./tools -name '*.rs' | xargs rustfmt --check --color auto
@find ./rustls -name '*.rs' | xargs rustfmt --check --color auto

fix-format:
@find ./cdylib -name '*.rs' | xargs rustfmt
@find ./ossl -name '*.rs' | xargs rustfmt --edition 2021
@find ./src -name '*.rs' | xargs rustfmt --edition 2021
@find ./tools -name '*.rs' | xargs rustfmt
@find ./rustls -name '*.rs' | xargs rustfmt

check-spell:
@.github/codespell.sh
Expand Down
3 changes: 3 additions & 0 deletions ossl/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ fn ossl_bindings(args: &mut Vec<String>, out_file: &Path) {
.allowlist_item("LN_aes.*")
.allowlist_item("ERR.*")
.allowlist_item("BIO.*")
.allowlist_item("i2d.*")
.allowlist_item("d2i.*")
.allowlist_item("RAND.*")
.blocklist_item("evp_pkey_ctx_st__.*")
.opaque_type("ecx_key_st")
.opaque_type("evp_pkey_ctx_st")
Expand Down
5 changes: 5 additions & 0 deletions ossl/ossl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
#include "openssl/err.h"
#include "openssl/provider.h"

#ifndef _KRYOPTIC_FIPS_
#include "openssl/rand.h"
#include "openssl/x509.h"
#endif

#ifdef _KRYOPTIC_FIPS_
#include "crypto/evp.h"
#include "openssl/fips_names.h"
Expand Down
33 changes: 32 additions & 1 deletion ossl/src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ pub enum EncAlg {
AesOfb(AesSize),
AesWrap(AesSize),
AesWrapPad(AesSize),
ChaCha20,
ChaCha20Poly1305,
/* 3DES */
#[cfg(feature = "rfc9580")]
TripleDesCfb,
Expand Down Expand Up @@ -233,6 +235,8 @@ fn cipher_to_name(alg: EncAlg) -> &'static CStr {
AesSize::Aes192 => c"AES-192-WRAP-PAD",
AesSize::Aes256 => c"AES-256-WRAP-PAD",
},
EncAlg::ChaCha20 => c"ChaCha20",
EncAlg::ChaCha20Poly1305 => c"ChaCha20-Poly1305",
#[cfg(feature = "rfc9580")]
EncAlg::TripleDesCfb => c"DES-EDE3-CFB",
#[cfg(feature = "rfc9580")]
Expand Down Expand Up @@ -370,7 +374,8 @@ impl OsslCipher {
EncAlg::AesCcm(_)
| EncAlg::AesGcm(_)
| EncAlg::AesGcmSiv(_)
| EncAlg::AesOcb(_) => ctx.aead_setup(alg, &aead)?,
| EncAlg::AesOcb(_)
| EncAlg::ChaCha20Poly1305 => ctx.aead_setup(alg, &aead)?,
EncAlg::AesCts(_, mode) => {
let mut params_builder = OsslParamBuilder::with_capacity(1);
params_builder.add_const_c_string(
Expand Down Expand Up @@ -613,6 +618,32 @@ impl OsslCipher {
Ok(usize::try_from(outlen)?)
}

/// Ingests plain text data and possibly outputs encrypted data in-place.
///
/// This api is equivalent to `update` but uses the same buffer for
/// input and output.
pub fn update_in_place(&mut self, data: &mut [u8]) -> Result<usize, Error> {
if data.len() < self.buffer_size(data.len()) {
return Err(Error::new(ErrorKind::BufferSize));
}

let mut outlen = c_int::try_from(data.len())?;
let ret = unsafe {
EVP_CipherUpdate(
self.ctx.as_mut_ptr(),
data.as_mut_ptr(),
&mut outlen,
data.as_ptr(),
c_int::try_from(data.len())?,
)
};
if ret != 1 {
trace_ossl!("EVP_CipherUpdate()");
return Err(Error::new(ErrorKind::OsslError));
}
Ok(usize::try_from(outlen)?)
}

/// Finalizes this encryption operation.
/// May return a final block of output.
pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, Error> {
Expand Down
72 changes: 69 additions & 3 deletions ossl/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,13 @@ impl<'a> OneStepKdfDerive<'a> {
if digest.is_some() {
return Err(Error::new(ErrorKind::WrapperError));
}
let (a, t) = mac_to_digest_and_type(m)?;
mac_type = Some(t);
a
match mac_to_digest_and_type(m) {
(Some(a), t) => {
mac_type = Some(t);
a
}
(None, _) => return Err(Error::new(ErrorKind::WrapperError)),
}
} else if let Some(a) = digest {
if mac.is_some() {
return Err(Error::new(ErrorKind::WrapperError));
Expand Down Expand Up @@ -955,3 +959,65 @@ impl FfdhDerive {
Ok(len)
}
}

const TLSPRF_MAX_SEEDS: usize = 6;

/// Higher level wrapper for TLS1 PRF Derive operation
#[derive(Debug)]
pub struct Tls1PrfDerive<'a> {
/// The OpenSSL KDF context (`EVP_KDF_CTX`).
ctx: EvpKdfCtx,
/// The digest function
digest: DigestAlg,
/// The derivation key (secret)
key: Option<&'a [u8]>,
/// Seeds
seeds: Vec<&'a [u8]>,
}

impl<'a> Tls1PrfDerive<'a> {
/// Instantiates a new Tls1PrfDerive context
pub fn new(
ctx: &OsslContext,
digest: DigestAlg,
) -> Result<Tls1PrfDerive<'a>, Error> {
Ok(Tls1PrfDerive {
ctx: EvpKdfCtx::new(ctx, cstr!(OSSL_KDF_NAME_TLS1_PRF))?,
digest: digest,
key: None,
seeds: Vec::with_capacity(TLSPRF_MAX_SEEDS),
})
}

/// Set the derivation key (secret)
pub fn set_key(&mut self, key: &'a [u8]) {
self.key = Some(key);
}

/// Add a seed
pub fn add_seed(&mut self, seed: &'a [u8]) {
self.seeds.push(seed);
}

/// Perform the derive operation based on the parameters set on the context
/// Returns the output in the provided output buffer
pub fn derive(&mut self, output: &mut [u8]) -> Result<(), Error> {
let mut params_builder =
OsslParamBuilder::with_capacity(2 + self.seeds.len());
params_builder.add_const_c_string(
cstr!(OSSL_KDF_PARAM_DIGEST),
digest_to_string(self.digest),
)?;
match &self.key {
Some(k) => params_builder
.add_octet_slice(cstr!(OSSL_KDF_PARAM_SECRET), k)?,
None => return Err(Error::new(ErrorKind::KeyError)),
}
for s in &self.seeds {
params_builder.add_octet_slice(cstr!(OSSL_KDF_PARAM_SEED), s)?
}
let params = params_builder.finalize();

self.ctx.derive(&params, output)
}
}
38 changes: 38 additions & 0 deletions ossl/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ impl EvpMdCtx {
}
}

#[cfg(ossl_v320)]
impl Clone for EvpMdCtx {
fn clone(&self) -> Self {
let ptr = unsafe { EVP_MD_CTX_dup(self.ptr) };
if ptr.is_null() {
panic!("EVP_MD_CTX_dup failed");
}
EvpMdCtx { ptr }
}
}

impl Drop for EvpMdCtx {
fn drop(&mut self) {
unsafe {
Expand Down Expand Up @@ -247,6 +258,22 @@ impl OsslDigest {
Ok(dctx)
}

pub fn available(ctx: &OsslContext, digest: DigestAlg) -> bool {
let name = digest_to_string(digest);
let arg = unsafe {
ERR_set_mark();
let m =
EVP_MD_fetch(ctx.ptr(), name.as_ptr(), std::ptr::null_mut());
ERR_pop_to_mark();
m
};
if !arg.is_null() {
unsafe { EVP_MD_free(arg) };
return true;
}
return false;
}
Comment thread
simo5 marked this conversation as resolved.

/// Re-initializes an existing context discarding any existing state
pub fn reset(&mut self, params: Option<&OsslParam>) -> Result<(), Error> {
let ret = unsafe {
Expand Down Expand Up @@ -346,5 +373,16 @@ impl OsslDigest {
}
}

#[cfg(ossl_v320)]
impl Clone for OsslDigest {
fn clone(&self) -> Self {
OsslDigest {
ctx: self.ctx.clone(),
md: self.md.clone(),
size: self.size,
}
}
}

unsafe impl Send for OsslDigest {}
unsafe impl Sync for OsslDigest {}
35 changes: 34 additions & 1 deletion ossl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ pub struct OsslContext {
}

static LEGACY_PROVIDER_NAME: &CStr = c"legacy";
static FIPS_PROVIDER_NAME: &CStr = c"fips";

impl OsslContext {
pub fn new_lib_ctx() -> OsslContext {
Expand Down Expand Up @@ -314,6 +315,38 @@ impl OsslContext {
}
}

pub fn load_fips_provider(&mut self) -> Result<(), Error> {
if unsafe {
OSSL_PROVIDER_available(self.ptr(), FIPS_PROVIDER_NAME.as_ptr())
} == 1
{
return Ok(());
}

let provider = unsafe {
OSSL_PROVIDER_load(self.ptr(), FIPS_PROVIDER_NAME.as_ptr())
};
if provider.is_null() {
Err(Error::new(ErrorKind::OsslError))
} else {
self.providers.push(provider);
Ok(())
}
}

pub fn enforce_fips(&mut self) -> Result<(), Error> {
self.load_fips_provider()?;
if unsafe { EVP_default_properties_enable_fips(self.ptr(), 1) } != 1 {
trace_ossl!("EVP_default_properties_enable_fips()");
return Err(Error::new(ErrorKind::OsslError));
}
Ok(())
}

pub fn fips_is_enabled(&self) -> bool {
unsafe { EVP_default_properties_is_fips_enabled(self.ptr()) == 1 }
}

pub fn ptr(&self) -> *mut OSSL_LIB_CTX {
self.context
}
Expand Down Expand Up @@ -1117,7 +1150,7 @@ impl<'a> OsslParam<'a> {
/// Once created, the capacity of an `OsslSecret` cannot be changed, preventing
/// accidental reallocations that might leave copies of the secret data in
/// unmanaged memory.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct OsslSecret {
data: Vec<u8>,
}
Expand Down
Loading
Loading