Skip to content
Merged
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
38 changes: 25 additions & 13 deletions src/rust/src/backend/cmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// for complete details.

use cryptography_crypto::constant_time;
use pyo3::types::{PyAnyMethods, PyBytesMethods};
use pyo3::types::PyAnyMethods;

use crate::backend::cipher_registry;
use crate::buf::CffiBuf;
Expand All @@ -19,10 +19,26 @@ struct Cmac {
}

impl Cmac {
fn new_bytes(key: &[u8], cipher: &openssl::cipher::CipherRef) -> CryptographyResult<Self> {
let ctx = cryptography_openssl::cmac::Cmac::new(key, cipher)?;
Ok(Cmac { ctx: Some(ctx) })
}

fn update_bytes(&mut self, data: &[u8]) -> CryptographyResult<()> {
self.get_mut_ctx()?.update(data)?;
Ok(())
}

fn finalize_bytes(&mut self) -> CryptographyResult<cryptography_openssl::hmac::DigestBytes> {
let data = self.get_mut_ctx()?.finish()?;
self.ctx = None;
Ok(data)
}

fn get_ctx(&self) -> CryptographyResult<&cryptography_openssl::cmac::Cmac> {
if let Some(ctx) = self.ctx.as_ref() {
return Ok(ctx);
};
}
Err(exceptions::already_finalized_error())
}

Expand Down Expand Up @@ -64,33 +80,29 @@ impl Cmac {
let key = algorithm
.getattr(pyo3::intern!(py, "key"))?
.extract::<CffiBuf<'_>>()?;
let ctx = cryptography_openssl::cmac::Cmac::new(key.as_bytes(), cipher)?;
Ok(Cmac { ctx: Some(ctx) })

Cmac::new_bytes(key.as_bytes(), cipher)
}

fn update(&mut self, data: CffiBuf<'_>) -> CryptographyResult<()> {
self.get_mut_ctx()?.update(data.as_bytes())?;
Ok(())
self.update_bytes(data.as_bytes())
}

fn finalize<'p>(
&mut self,
py: pyo3::Python<'p>,
) -> CryptographyResult<pyo3::Bound<'p, pyo3::types::PyBytes>> {
let data = self.get_mut_ctx()?.finish()?;
self.ctx = None;
let data = self.finalize_bytes()?;
Ok(pyo3::types::PyBytes::new(py, &data))
}

fn verify(&mut self, py: pyo3::Python<'_>, signature: &[u8]) -> CryptographyResult<()> {
let actual = self.finalize(py)?;
let actual = actual.as_bytes();
if !constant_time::bytes_eq(actual, signature) {
fn verify(&mut self, _py: pyo3::Python<'_>, signature: &[u8]) -> CryptographyResult<()> {
let actual = self.finalize_bytes()?;
if !constant_time::bytes_eq(&actual, signature) {
return Err(CryptographyError::from(
exceptions::InvalidSignature::new_err("Signature did not match digest."),
));
}

Ok(())
}

Expand Down
Loading