changed indentation to spaces

This commit is contained in:
mamoniot 2023-02-27 10:46:11 -05:00
commit 29b0800798
No known key found for this signature in database
GPG key ID: ADCCDBBE0E3D3B3B
3 changed files with 3559 additions and 3559 deletions

File diff suppressed because it is too large Load diff

View file

@ -6,163 +6,163 @@ use foreign_types::{ForeignType, foreign_type, ForeignTypeRef};
use libc::c_int; use libc::c_int;
foreign_type! { foreign_type! {
pub unsafe type CipherCtx { pub unsafe type CipherCtx {
type CType = ffi::EVP_CIPHER_CTX; type CType = ffi::EVP_CIPHER_CTX;
fn drop = ffi::EVP_CIPHER_CTX_free; fn drop = ffi::EVP_CIPHER_CTX_free;
} }
} }
impl CipherCtx { impl CipherCtx {
/// Creates a new context. /// Creates a new context.
pub fn new() -> Result<Self, ErrorStack> { pub fn new() -> Result<Self, ErrorStack> {
unsafe { unsafe {
let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?; let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
Ok(CipherCtx::from_ptr(ptr)) Ok(CipherCtx::from_ptr(ptr))
} }
} }
} }
impl CipherCtxRef { impl CipherCtxRef {
/// Initializes the context for encryption or decryption. /// Initializes the context for encryption or decryption.
/// All pointer fields can be null, in which case the corresponding field in the context is not updated. /// All pointer fields can be null, in which case the corresponding field in the context is not updated.
pub unsafe fn cipher_init<const ENCRYPT: bool>(&mut self, t: *const ffi::EVP_CIPHER, key: *const u8, iv: *const u8) -> Result<(), ErrorStack>{ pub unsafe fn cipher_init<const ENCRYPT: bool>(&mut self, t: *const ffi::EVP_CIPHER, key: *const u8, iv: *const u8) -> Result<(), ErrorStack>{
let evp_f = if ENCRYPT { ffi::EVP_EncryptInit_ex } else { ffi::EVP_DecryptInit_ex }; let evp_f = if ENCRYPT { ffi::EVP_EncryptInit_ex } else { ffi::EVP_DecryptInit_ex };
cvt(evp_f( cvt(evp_f(
self.as_ptr(), self.as_ptr(),
t, t,
ptr::null_mut(), ptr::null_mut(),
key, key,
iv, iv,
))?; ))?;
Ok(()) Ok(())
} }
/// Writes data into the context. /// Writes data into the context.
/// ///
/// Providing no output buffer will cause the input to be considered additional authenticated data (AAD). /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD).
/// ///
/// Returns the number of bytes written to `output`. /// Returns the number of bytes written to `output`.
/// ///
/// This function is the same as [`Self::cipher_update`] but with the /// This function is the same as [`Self::cipher_update`] but with the
/// output size check removed. It can be used when the exact /// output size check removed. It can be used when the exact
/// buffer size control is maintained by the caller. /// buffer size control is maintained by the caller.
/// ///
/// SAFETY: The caller is expected to provide `output` buffer /// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming /// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer size should be at least as big as /// ciphers the output buffer size should be at least as big as
/// the input buffer. For block ciphers the size of the output /// the input buffer. For block ciphers the size of the output
/// buffer depends on the state of partially updated blocks. /// buffer depends on the state of partially updated blocks.
pub unsafe fn update<const ENCRYPT: bool>( pub unsafe fn update<const ENCRYPT: bool>(
&mut self, &mut self,
input: &[u8], input: &[u8],
output: *mut u8, output: *mut u8,
) -> Result<(), ErrorStack> { ) -> Result<(), ErrorStack> {
let evp_f = if ENCRYPT { ffi::EVP_EncryptUpdate } else { ffi::EVP_DecryptUpdate }; let evp_f = if ENCRYPT { ffi::EVP_EncryptUpdate } else { ffi::EVP_DecryptUpdate };
let mut outlen = 0; let mut outlen = 0;
cvt(evp_f( cvt(evp_f(
self.as_ptr(), self.as_ptr(),
output, output,
&mut outlen, &mut outlen,
input.as_ptr(), input.as_ptr(),
input.len() as c_int, input.len() as c_int,
))?; ))?;
Ok(()) Ok(())
} }
/// Finalizes the encryption or decryption process. /// Finalizes the encryption or decryption process.
/// ///
/// Any remaining data will be written to the output buffer. /// Any remaining data will be written to the output buffer.
/// ///
/// Returns the number of bytes written to `output`. /// Returns the number of bytes written to `output`.
/// ///
/// This function is the same as [`Self::cipher_final`] but with /// This function is the same as [`Self::cipher_final`] but with
/// the output buffer size check removed. /// the output buffer size check removed.
/// ///
/// SAFETY: The caller is expected to provide `output` buffer /// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming /// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer can be empty, for block ciphers the /// ciphers the output buffer can be empty, for block ciphers the
/// output buffer should be at least as big as the block. /// output buffer should be at least as big as the block.
pub unsafe fn finalize<const ENCRYPT: bool>( pub unsafe fn finalize<const ENCRYPT: bool>(
&mut self, &mut self,
output: *mut u8, output: *mut u8,
) -> Result<(), ErrorStack> { ) -> Result<(), ErrorStack> {
let evp_f = if ENCRYPT { ffi::EVP_EncryptFinal_ex } else { ffi::EVP_DecryptFinal_ex }; let evp_f = if ENCRYPT { ffi::EVP_EncryptFinal_ex } else { ffi::EVP_DecryptFinal_ex };
let mut outl = 0; let mut outl = 0;
cvt(evp_f( cvt(evp_f(
self.as_ptr(), self.as_ptr(),
output, output,
&mut outl, &mut outl,
))?; ))?;
Ok(()) Ok(())
} }
/// Retrieves the calculated authentication tag from the context. /// Retrieves the calculated authentication tag from the context.
/// ///
/// This should be called after [`Self::cipher_final`], and is only supported by authenticated ciphers. /// This should be called after [`Self::cipher_final`], and is only supported by authenticated ciphers.
/// ///
/// The size of the buffer indicates the size of the tag. While some ciphers support a range of tag sizes, it is /// The size of the buffer indicates the size of the tag. While some ciphers support a range of tag sizes, it is
/// recommended to pick the maximum size. /// recommended to pick the maximum size.
pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> { pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::EVP_CIPHER_CTX_ctrl( cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.as_ptr(), self.as_ptr(),
ffi::EVP_CTRL_GCM_GET_TAG, ffi::EVP_CTRL_GCM_GET_TAG,
tag.len() as c_int, tag.len() as c_int,
tag.as_mut_ptr() as *mut _, tag.as_mut_ptr() as *mut _,
))?; ))?;
} }
Ok(()) Ok(())
} }
/// Sets the authentication tag for verification during decryption. /// Sets the authentication tag for verification during decryption.
pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> { pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::EVP_CIPHER_CTX_ctrl( cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.as_ptr(), self.as_ptr(),
ffi::EVP_CTRL_GCM_SET_TAG, ffi::EVP_CTRL_GCM_SET_TAG,
tag.len() as c_int, tag.len() as c_int,
tag.as_ptr() as *mut _, tag.as_ptr() as *mut _,
))?; ))?;
} }
Ok(()) Ok(())
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::init; use crate::init;
use super::*; use super::*;
#[test] #[test]
fn aes_128_ecb() { fn aes_128_ecb() {
init(); init();
let key = [1u8; 16]; let key = [1u8; 16];
let mut ctx = CipherCtx::new().unwrap(); let mut ctx = CipherCtx::new().unwrap();
unsafe { unsafe {
ctx.cipher_init::<true>(ffi::EVP_aes_128_ecb(), key.as_ptr(), ptr::null()).unwrap(); ctx.cipher_init::<true>(ffi::EVP_aes_128_ecb(), key.as_ptr(), ptr::null()).unwrap();
ffi::EVP_CIPHER_CTX_set_padding(ctx.as_ptr(), 0); ffi::EVP_CIPHER_CTX_set_padding(ctx.as_ptr(), 0);
assert_eq!(ffi::EVP_CIPHER_CTX_get_block_size(ctx.as_ptr()) as usize, 16); assert_eq!(ffi::EVP_CIPHER_CTX_get_block_size(ctx.as_ptr()) as usize, 16);
let origin = [2u8; 16]; let origin = [2u8; 16];
let mut val = origin.clone(); let mut val = origin.clone();
let p = val.as_mut_ptr(); let p = val.as_mut_ptr();
ctx.update::<true>(&val, p).unwrap(); ctx.update::<true>(&val, p).unwrap();
ctx.cipher_init::<false>(ptr::null(), key.as_ptr(), ptr::null()).unwrap(); ctx.cipher_init::<false>(ptr::null(), key.as_ptr(), ptr::null()).unwrap();
ctx.update::<false>(&val, p).unwrap(); ctx.update::<false>(&val, p).unwrap();
assert_eq!(val, origin); assert_eq!(val, origin);
} }
} }
} }

View file

@ -14,62 +14,62 @@ pub const HMAC_SHA384_SIZE: usize = 48;
pub struct SHA512(ffi::SHA512_CTX); pub struct SHA512(ffi::SHA512_CTX);
impl SHA512 { impl SHA512 {
#[inline(always)] #[inline(always)]
pub fn hash(data: &[u8]) -> [u8; SHA512_HASH_SIZE] { pub fn hash(data: &[u8]) -> [u8; SHA512_HASH_SIZE] {
unsafe { unsafe {
let mut hash = MaybeUninit::<[u8; 64]>::uninit(); let mut hash = MaybeUninit::<[u8; 64]>::uninit();
ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _);
hash.assume_init() hash.assume_init()
} }
} }
/// Creates a new hasher. /// Creates a new hasher.
#[inline(always)] #[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
unsafe { unsafe {
let mut ctx = MaybeUninit::uninit(); let mut ctx = MaybeUninit::uninit();
ffi::SHA512_Init(ctx.as_mut_ptr()); ffi::SHA512_Init(ctx.as_mut_ptr());
SHA512(ctx.assume_init()) SHA512(ctx.assume_init())
} }
} }
/// Feeds some data into the hasher. /// Feeds some data into the hasher.
/// ///
/// This can be called multiple times. /// This can be called multiple times.
#[inline(always)] #[inline(always)]
pub fn reset(&mut self) { pub fn reset(&mut self) {
unsafe { ffi::SHA512_Init(&mut self.0) }; unsafe { ffi::SHA512_Init(&mut self.0) };
} }
#[inline(always)] #[inline(always)]
pub fn update(&mut self, buf: &[u8]) { pub fn update(&mut self, buf: &[u8]) {
unsafe { unsafe {
ffi::SHA512_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); ffi::SHA512_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
} }
} }
/// Returns the hash of the data. /// Returns the hash of the data.
#[inline(always)] #[inline(always)]
pub fn finish(&mut self) -> [u8; SHA512_HASH_SIZE] { pub fn finish(&mut self) -> [u8; SHA512_HASH_SIZE] {
unsafe { unsafe {
let mut hash = MaybeUninit::<[u8; 64]>::uninit(); let mut hash = MaybeUninit::<[u8; 64]>::uninit();
ffi::SHA512_Final(hash.as_mut_ptr() as *mut _, &mut self.0); ffi::SHA512_Final(hash.as_mut_ptr() as *mut _, &mut self.0);
hash.assume_init() hash.assume_init()
} }
} }
} }
impl Write for SHA512 { impl Write for SHA512 {
#[inline(always)] #[inline(always)]
fn write(&mut self, b: &[u8]) -> std::io::Result<usize> { fn write(&mut self, b: &[u8]) -> std::io::Result<usize> {
self.update(b); self.update(b);
Ok(b.len()) Ok(b.len())
} }
#[inline(always)] #[inline(always)]
fn flush(&mut self) -> std::io::Result<()> { fn flush(&mut self) -> std::io::Result<()> {
Ok(()) Ok(())
} }
} }
unsafe impl Send for SHA512 {} unsafe impl Send for SHA512 {}
@ -77,213 +77,213 @@ unsafe impl Send for SHA512 {}
pub struct SHA384(ffi::SHA512_CTX); pub struct SHA384(ffi::SHA512_CTX);
impl SHA384 { impl SHA384 {
#[inline(always)] #[inline(always)]
pub fn hash(data: &[u8]) -> [u8; SHA384_HASH_SIZE] { pub fn hash(data: &[u8]) -> [u8; SHA384_HASH_SIZE] {
unsafe { unsafe {
let mut hash = MaybeUninit::<[u8; 48]>::uninit(); let mut hash = MaybeUninit::<[u8; 48]>::uninit();
ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _);
hash.assume_init() hash.assume_init()
} }
} }
#[inline(always)] #[inline(always)]
pub fn new() -> Self { pub fn new() -> Self {
unsafe { unsafe {
let mut ctx = MaybeUninit::uninit(); let mut ctx = MaybeUninit::uninit();
ffi::SHA384_Init(ctx.as_mut_ptr()); ffi::SHA384_Init(ctx.as_mut_ptr());
SHA384(ctx.assume_init()) SHA384(ctx.assume_init())
} }
} }
#[inline(always)] #[inline(always)]
pub fn reset(&mut self) { pub fn reset(&mut self) {
unsafe { unsafe {
ffi::SHA384_Init(&mut self.0); ffi::SHA384_Init(&mut self.0);
} }
} }
#[inline(always)] #[inline(always)]
pub fn update(&mut self, buf: &[u8]) { pub fn update(&mut self, buf: &[u8]) {
unsafe { unsafe {
ffi::SHA384_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); ffi::SHA384_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
} }
} }
#[inline(always)] #[inline(always)]
pub fn finish(&mut self) -> [u8; SHA384_HASH_SIZE] { pub fn finish(&mut self) -> [u8; SHA384_HASH_SIZE] {
unsafe { unsafe {
let mut hash = MaybeUninit::<[u8; 48]>::uninit(); let mut hash = MaybeUninit::<[u8; 48]>::uninit();
ffi::SHA384_Final(hash.as_mut_ptr() as *mut _, &mut self.0); ffi::SHA384_Final(hash.as_mut_ptr() as *mut _, &mut self.0);
hash.assume_init() hash.assume_init()
} }
} }
} }
impl Write for SHA384 { impl Write for SHA384 {
#[inline(always)] #[inline(always)]
fn write(&mut self, b: &[u8]) -> std::io::Result<usize> { fn write(&mut self, b: &[u8]) -> std::io::Result<usize> {
self.update(b); self.update(b);
Ok(b.len()) Ok(b.len())
} }
#[inline(always)] #[inline(always)]
fn flush(&mut self) -> std::io::Result<()> { fn flush(&mut self) -> std::io::Result<()> {
Ok(()) Ok(())
} }
} }
unsafe impl Send for SHA384 {} unsafe impl Send for SHA384 {}
//#[link(name="crypto")] //#[link(name="crypto")]
extern "C" { extern "C" {
fn HMAC_CTX_new() -> *mut c_void; fn HMAC_CTX_new() -> *mut c_void;
fn HMAC_CTX_reset(ctx: *mut c_void) -> c_int; fn HMAC_CTX_reset(ctx: *mut c_void) -> c_int;
fn HMAC_Init_ex(ctx: *mut c_void, key: *const c_void, key_len: c_int, evp_md: *const c_void, _impl: *const c_void) -> c_int; fn HMAC_Init_ex(ctx: *mut c_void, key: *const c_void, key_len: c_int, evp_md: *const c_void, _impl: *const c_void) -> c_int;
fn HMAC_Update(ctx: *mut c_void, data: *const c_void, len: usize) -> c_int; fn HMAC_Update(ctx: *mut c_void, data: *const c_void, len: usize) -> c_int;
fn HMAC_Final(ctx: *mut c_void, output: *mut c_void, output_len: *mut c_uint) -> c_int; fn HMAC_Final(ctx: *mut c_void, output: *mut c_void, output_len: *mut c_uint) -> c_int;
fn HMAC_CTX_free(ctx: *mut c_void); fn HMAC_CTX_free(ctx: *mut c_void);
fn EVP_sha384() -> *const c_void; fn EVP_sha384() -> *const c_void;
fn EVP_sha512() -> *const c_void; fn EVP_sha512() -> *const c_void;
} }
pub struct HMACSHA512 { pub struct HMACSHA512 {
ctx: *mut c_void, ctx: *mut c_void,
evp_md: *const c_void, evp_md: *const c_void,
} }
impl HMACSHA512 { impl HMACSHA512 {
#[inline(always)] #[inline(always)]
pub fn new(key: &[u8]) -> Self { pub fn new(key: &[u8]) -> Self {
unsafe { unsafe {
let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha512() }; let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha512() };
assert!(!hm.ctx.is_null()); assert!(!hm.ctx.is_null());
assert_ne!(HMAC_Init_ex(hm.ctx, key.as_ptr().cast(), key.len() as c_int, hm.evp_md, null()), 0); assert_ne!(HMAC_Init_ex(hm.ctx, key.as_ptr().cast(), key.len() as c_int, hm.evp_md, null()), 0);
hm hm
} }
} }
#[inline(always)] #[inline(always)]
pub fn reset(&mut self) { pub fn reset(&mut self) {
unsafe { unsafe {
assert_ne!(HMAC_CTX_reset(self.ctx), 0); assert_ne!(HMAC_CTX_reset(self.ctx), 0);
} }
} }
#[inline(always)] #[inline(always)]
pub fn update(&mut self, b: &[u8]) { pub fn update(&mut self, b: &[u8]) {
unsafe { unsafe {
assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0); assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0);
} }
} }
#[inline(always)] #[inline(always)]
pub fn finish_into(&mut self, md: &mut [u8]) { pub fn finish_into(&mut self, md: &mut [u8]) {
unsafe { unsafe {
assert_eq!(md.len(), 64); assert_eq!(md.len(), 64);
let mut mdlen: c_uint = 64; let mut mdlen: c_uint = 64;
assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0); assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0);
assert_eq!(mdlen, 64); assert_eq!(mdlen, 64);
} }
} }
#[inline(always)] #[inline(always)]
pub fn finish(&mut self) -> [u8; 64] { pub fn finish(&mut self) -> [u8; 64] {
let mut tmp = [0u8; 64]; let mut tmp = [0u8; 64];
self.finish_into(&mut tmp); self.finish_into(&mut tmp);
tmp tmp
} }
} }
impl Drop for HMACSHA512 { impl Drop for HMACSHA512 {
#[inline(always)] #[inline(always)]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { HMAC_CTX_free(self.ctx) }; unsafe { HMAC_CTX_free(self.ctx) };
} }
} }
unsafe impl Send for HMACSHA512 {} unsafe impl Send for HMACSHA512 {}
pub struct HMACSHA384 { pub struct HMACSHA384 {
ctx: *mut c_void, ctx: *mut c_void,
evp_md: *const c_void, evp_md: *const c_void,
} }
impl HMACSHA384 { impl HMACSHA384 {
#[inline(always)] #[inline(always)]
pub fn new(key: &[u8]) -> Self { pub fn new(key: &[u8]) -> Self {
unsafe { unsafe {
let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha384() }; let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha384() };
assert!(!hm.ctx.is_null()); assert!(!hm.ctx.is_null());
assert_ne!(HMAC_Init_ex(hm.ctx, key.as_ptr().cast(), key.len() as c_int, hm.evp_md, null()), 0); assert_ne!(HMAC_Init_ex(hm.ctx, key.as_ptr().cast(), key.len() as c_int, hm.evp_md, null()), 0);
hm hm
} }
} }
#[inline(always)] #[inline(always)]
pub fn reset(&mut self) { pub fn reset(&mut self) {
unsafe { unsafe {
assert_ne!(HMAC_CTX_reset(self.ctx), 0); assert_ne!(HMAC_CTX_reset(self.ctx), 0);
} }
} }
#[inline(always)] #[inline(always)]
pub fn update(&mut self, b: &[u8]) { pub fn update(&mut self, b: &[u8]) {
unsafe { unsafe {
assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0); assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0);
} }
} }
#[inline(always)] #[inline(always)]
pub fn finish_into(&mut self, md: &mut [u8]) { pub fn finish_into(&mut self, md: &mut [u8]) {
unsafe { unsafe {
assert_eq!(md.len(), 48); assert_eq!(md.len(), 48);
let mut mdlen: c_uint = 48; let mut mdlen: c_uint = 48;
assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0); assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0);
assert_eq!(mdlen, 48); assert_eq!(mdlen, 48);
} }
} }
#[inline(always)] #[inline(always)]
pub fn finish(&mut self) -> [u8; 48] { pub fn finish(&mut self) -> [u8; 48] {
let mut tmp = [0u8; 48]; let mut tmp = [0u8; 48];
self.finish_into(&mut tmp); self.finish_into(&mut tmp);
tmp tmp
} }
} }
impl Drop for HMACSHA384 { impl Drop for HMACSHA384 {
#[inline(always)] #[inline(always)]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { HMAC_CTX_free(self.ctx) }; unsafe { HMAC_CTX_free(self.ctx) };
} }
} }
unsafe impl Send for HMACSHA384 {} unsafe impl Send for HMACSHA384 {}
#[inline(always)] #[inline(always)]
pub fn hmac_sha512(key: &[u8], msg: &[u8]) -> [u8; 64] { pub fn hmac_sha512(key: &[u8], msg: &[u8]) -> [u8; 64] {
let mut hm = HMACSHA512::new(key); let mut hm = HMACSHA512::new(key);
hm.update(msg); hm.update(msg);
hm.finish() hm.finish()
} }
#[inline(always)] #[inline(always)]
pub fn hmac_sha512_into(key: &[u8], msg: &[u8], md: &mut [u8]) { pub fn hmac_sha512_into(key: &[u8], msg: &[u8], md: &mut [u8]) {
let mut hm = HMACSHA512::new(key); let mut hm = HMACSHA512::new(key);
hm.update(msg); hm.update(msg);
hm.finish_into(md); hm.finish_into(md);
} }
#[inline(always)] #[inline(always)]
pub fn hmac_sha384(key: &[u8], msg: &[u8]) -> [u8; 48] { pub fn hmac_sha384(key: &[u8], msg: &[u8]) -> [u8; 48] {
let mut hm = HMACSHA384::new(key); let mut hm = HMACSHA384::new(key);
hm.update(msg); hm.update(msg);
hm.finish() hm.finish()
} }
#[inline(always)] #[inline(always)]
pub fn hmac_sha384_into(key: &[u8], msg: &[u8], md: &mut [u8]) { pub fn hmac_sha384_into(key: &[u8], msg: &[u8], md: &mut [u8]) {
let mut hm = HMACSHA384::new(key); let mut hm = HMACSHA384::new(key);
hm.update(msg); hm.update(msg);
hm.finish_into(md); hm.finish_into(md);
} }