Unverified Commit b404efb9 authored by Steven Fackler's avatar Steven Fackler
Browse files

Cipher::fetch

parent 9749c233
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -127,4 +127,9 @@ extern "C" {
    pub fn FIPS_mode_set(onoff: c_int) -> c_int;

    pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void, len: size_t) -> c_int;

    #[cfg(ossl300)]
    pub fn OSSL_LIB_CTX_new() -> *mut OSSL_LIB_CTX;
    #[cfg(ossl300)]
    pub fn OSSL_LIB_CTX_free(libcts: *mut OSSL_LIB_CTX);
}
+5 −0
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@ cfg_if! {
            pub fn EVP_CIPHER_get_block_size(cipher: *const EVP_CIPHER) -> c_int;
            pub fn EVP_CIPHER_get_iv_length(cipher: *const EVP_CIPHER) -> c_int;
            pub fn EVP_CIPHER_get_nid(cipher: *const EVP_CIPHER) -> c_int;
            pub fn EVP_CIPHER_fetch(
                ctx: *mut OSSL_LIB_CTX,
                algorithm: *const c_char,
                properties: *const c_char,
            ) -> *mut EVP_CIPHER;
            pub fn EVP_CIPHER_free(cipher: *mut EVP_CIPHER);

            pub fn EVP_CIPHER_CTX_get0_cipher(ctx: *const EVP_CIPHER_CTX) -> *const EVP_CIPHER;
+37 −0
Original line number Diff line number Diff line
//! Symmetric ciphers.

#[cfg(ossl300)]
use crate::cvt_p;
#[cfg(ossl300)]
use crate::error::ErrorStack;
#[cfg(ossl300)]
use crate::lib_ctx::LibCtxRef;
use crate::nid::Nid;
use cfg_if::cfg_if;
use foreign_types::{ForeignTypeRef, Opaque};
#[cfg(ossl300)]
use std::ffi::CString;
#[cfg(ossl300)]
use std::ptr;

cfg_if! {
    if #[cfg(any(ossl110, libressl273))] {
@@ -105,6 +115,33 @@ impl Cipher {
        }
    }

    /// Fetches a cipher object corresponding to the specified algorithm name and properties.
    ///
    /// This corresponds to [`EVP_CIPHER_fetch`].
    ///
    /// Requires OpenSSL 3.0.0 or newer.
    ///
    /// [`EVP_CIPHER_fetch`]: https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_fetch.html
    #[cfg(ossl300)]
    pub fn fetch(
        ctx: Option<&LibCtxRef>,
        algorithm: &str,
        properties: Option<&str>,
    ) -> Result<Self, ErrorStack> {
        let algorithm = CString::new(algorithm).unwrap();
        let properties = properties.map(|s| CString::new(s).unwrap());

        unsafe {
            let ptr = cvt_p(ffi::EVP_CIPHER_fetch(
                ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
                algorithm.as_ptr(),
                properties.map_or(ptr::null_mut(), |s| s.as_ptr()),
            ))?;

            Ok(Cipher::from_ptr(ptr))
        }
    }

    pub fn aes_128_ecb() -> &'static CipherRef {
        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) }
    }
+44 −0
Original line number Diff line number Diff line
@@ -669,4 +669,48 @@ mod test {

        assert_eq!(secret, &decrypted[..]);
    }

    fn aes_128_cbc(cipher: &CipherRef) {
        // from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
        let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
        let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
        let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
            .unwrap();
        let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
            .unwrap();

        let mut ctx = CipherCtx::new().unwrap();
        ctx.set_padding(false);

        ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
            .unwrap();

        let mut buf = vec![];
        ctx.cipher_update_vec(&pt, &mut buf).unwrap();
        ctx.cipher_final_vec(&mut buf).unwrap();

        assert_eq!(buf, ct);

        ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
            .unwrap();

        let mut buf = vec![];
        ctx.cipher_update_vec(&ct, &mut buf).unwrap();
        ctx.cipher_final_vec(&mut buf).unwrap();

        assert_eq!(buf, pt);
    }

    #[test]
    #[cfg(ossl300)]
    fn fetched_aes_128_cbc() {
        let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
        aes_128_cbc(&cipher);
    }

    #[test]
    fn default_aes_128_cbc() {
        let cipher = Cipher::aes_128_cbc();
        aes_128_cbc(cipher);
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -151,6 +151,8 @@ pub mod ex_data;
#[cfg(not(any(libressl, ossl300)))]
pub mod fips;
pub mod hash;
#[cfg(ossl300)]
pub mod lib_ctx;
pub mod memcmp;
pub mod nid;
#[cfg(not(osslconf = "OPENSSL_NO_OCSP"))]
Loading