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;
foreign_type! {
pub unsafe type CipherCtx {
type CType = ffi::EVP_CIPHER_CTX;
fn drop = ffi::EVP_CIPHER_CTX_free;
}
pub unsafe type CipherCtx {
type CType = ffi::EVP_CIPHER_CTX;
fn drop = ffi::EVP_CIPHER_CTX_free;
}
}
impl CipherCtx {
/// Creates a new context.
pub fn new() -> Result<Self, ErrorStack> {
unsafe {
let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
Ok(CipherCtx::from_ptr(ptr))
}
}
/// Creates a new context.
pub fn new() -> Result<Self, ErrorStack> {
unsafe {
let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
Ok(CipherCtx::from_ptr(ptr))
}
}
}
impl CipherCtxRef {
/// 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.
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 };
/// 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.
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 };
cvt(evp_f(
self.as_ptr(),
t,
ptr::null_mut(),
key,
iv,
))?;
Ok(())
}
cvt(evp_f(
self.as_ptr(),
t,
ptr::null_mut(),
key,
iv,
))?;
Ok(())
}
/// Writes data into the context.
///
/// Providing no output buffer will cause the input to be considered additional authenticated data (AAD).
///
/// Returns the number of bytes written to `output`.
///
/// This function is the same as [`Self::cipher_update`] but with the
/// output size check removed. It can be used when the exact
/// buffer size control is maintained by the caller.
///
/// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer size should be at least as big as
/// the input buffer. For block ciphers the size of the output
/// buffer depends on the state of partially updated blocks.
pub unsafe fn update<const ENCRYPT: bool>(
&mut self,
input: &[u8],
output: *mut u8,
) -> Result<(), ErrorStack> {
let evp_f = if ENCRYPT { ffi::EVP_EncryptUpdate } else { ffi::EVP_DecryptUpdate };
/// Writes data into the context.
///
/// Providing no output buffer will cause the input to be considered additional authenticated data (AAD).
///
/// Returns the number of bytes written to `output`.
///
/// This function is the same as [`Self::cipher_update`] but with the
/// output size check removed. It can be used when the exact
/// buffer size control is maintained by the caller.
///
/// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer size should be at least as big as
/// the input buffer. For block ciphers the size of the output
/// buffer depends on the state of partially updated blocks.
pub unsafe fn update<const ENCRYPT: bool>(
&mut self,
input: &[u8],
output: *mut u8,
) -> Result<(), ErrorStack> {
let evp_f = if ENCRYPT { ffi::EVP_EncryptUpdate } else { ffi::EVP_DecryptUpdate };
let mut outlen = 0;
let mut outlen = 0;
cvt(evp_f(
self.as_ptr(),
output,
&mut outlen,
input.as_ptr(),
input.len() as c_int,
))?;
cvt(evp_f(
self.as_ptr(),
output,
&mut outlen,
input.as_ptr(),
input.len() as c_int,
))?;
Ok(())
}
Ok(())
}
/// Finalizes the encryption or decryption process.
///
/// Any remaining data will be written to the output buffer.
///
/// Returns the number of bytes written to `output`.
///
/// This function is the same as [`Self::cipher_final`] but with
/// the output buffer size check removed.
///
/// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer can be empty, for block ciphers the
/// output buffer should be at least as big as the block.
pub unsafe fn finalize<const ENCRYPT: bool>(
&mut self,
output: *mut u8,
) -> Result<(), ErrorStack> {
let evp_f = if ENCRYPT { ffi::EVP_EncryptFinal_ex } else { ffi::EVP_DecryptFinal_ex };
let mut outl = 0;
/// Finalizes the encryption or decryption process.
///
/// Any remaining data will be written to the output buffer.
///
/// Returns the number of bytes written to `output`.
///
/// This function is the same as [`Self::cipher_final`] but with
/// the output buffer size check removed.
///
/// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer can be empty, for block ciphers the
/// output buffer should be at least as big as the block.
pub unsafe fn finalize<const ENCRYPT: bool>(
&mut self,
output: *mut u8,
) -> Result<(), ErrorStack> {
let evp_f = if ENCRYPT { ffi::EVP_EncryptFinal_ex } else { ffi::EVP_DecryptFinal_ex };
let mut outl = 0;
cvt(evp_f(
self.as_ptr(),
output,
&mut outl,
))?;
cvt(evp_f(
self.as_ptr(),
output,
&mut outl,
))?;
Ok(())
}
Ok(())
}
/// Retrieves the calculated authentication tag from the context.
///
/// 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
/// recommended to pick the maximum size.
pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
/// Retrieves the calculated authentication tag from the context.
///
/// 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
/// recommended to pick the maximum size.
pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.as_ptr(),
ffi::EVP_CTRL_GCM_GET_TAG,
tag.len() as c_int,
tag.as_mut_ptr() as *mut _,
))?;
}
unsafe {
cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.as_ptr(),
ffi::EVP_CTRL_GCM_GET_TAG,
tag.len() as c_int,
tag.as_mut_ptr() as *mut _,
))?;
}
Ok(())
}
Ok(())
}
/// Sets the authentication tag for verification during decryption.
pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.as_ptr(),
ffi::EVP_CTRL_GCM_SET_TAG,
tag.len() as c_int,
tag.as_ptr() as *mut _,
))?;
}
/// Sets the authentication tag for verification during decryption.
pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_CIPHER_CTX_ctrl(
self.as_ptr(),
ffi::EVP_CTRL_GCM_SET_TAG,
tag.len() as c_int,
tag.as_ptr() as *mut _,
))?;
}
Ok(())
}
Ok(())
}
}
#[cfg(test)]
mod test {
use crate::init;
use super::*;
use crate::init;
use super::*;
#[test]
fn aes_128_ecb() {
init();
let key = [1u8; 16];
let mut ctx = CipherCtx::new().unwrap();
unsafe {
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);
assert_eq!(ffi::EVP_CIPHER_CTX_get_block_size(ctx.as_ptr()) as usize, 16);
#[test]
fn aes_128_ecb() {
init();
let key = [1u8; 16];
let mut ctx = CipherCtx::new().unwrap();
unsafe {
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);
assert_eq!(ffi::EVP_CIPHER_CTX_get_block_size(ctx.as_ptr()) as usize, 16);
let origin = [2u8; 16];
let mut val = origin.clone();
let p = val.as_mut_ptr();
let origin = [2u8; 16];
let mut val = origin.clone();
let p = val.as_mut_ptr();
ctx.update::<true>(&val, p).unwrap();
ctx.cipher_init::<false>(ptr::null(), key.as_ptr(), ptr::null()).unwrap();
ctx.update::<false>(&val, p).unwrap();
ctx.update::<true>(&val, p).unwrap();
ctx.cipher_init::<false>(ptr::null(), key.as_ptr(), ptr::null()).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);
impl SHA512 {
#[inline(always)]
pub fn hash(data: &[u8]) -> [u8; SHA512_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 64]>::uninit();
ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _);
hash.assume_init()
}
}
#[inline(always)]
pub fn hash(data: &[u8]) -> [u8; SHA512_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 64]>::uninit();
ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _);
hash.assume_init()
}
}
/// Creates a new hasher.
#[inline(always)]
pub fn new() -> Self {
unsafe {
let mut ctx = MaybeUninit::uninit();
ffi::SHA512_Init(ctx.as_mut_ptr());
SHA512(ctx.assume_init())
}
}
/// Creates a new hasher.
#[inline(always)]
pub fn new() -> Self {
unsafe {
let mut ctx = MaybeUninit::uninit();
ffi::SHA512_Init(ctx.as_mut_ptr());
SHA512(ctx.assume_init())
}
}
/// Feeds some data into the hasher.
///
/// This can be called multiple times.
#[inline(always)]
pub fn reset(&mut self) {
unsafe { ffi::SHA512_Init(&mut self.0) };
}
/// Feeds some data into the hasher.
///
/// This can be called multiple times.
#[inline(always)]
pub fn reset(&mut self) {
unsafe { ffi::SHA512_Init(&mut self.0) };
}
#[inline(always)]
pub fn update(&mut self, buf: &[u8]) {
unsafe {
ffi::SHA512_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
}
}
#[inline(always)]
pub fn update(&mut self, buf: &[u8]) {
unsafe {
ffi::SHA512_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
}
}
/// Returns the hash of the data.
#[inline(always)]
pub fn finish(&mut self) -> [u8; SHA512_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 64]>::uninit();
ffi::SHA512_Final(hash.as_mut_ptr() as *mut _, &mut self.0);
hash.assume_init()
}
}
/// Returns the hash of the data.
#[inline(always)]
pub fn finish(&mut self) -> [u8; SHA512_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 64]>::uninit();
ffi::SHA512_Final(hash.as_mut_ptr() as *mut _, &mut self.0);
hash.assume_init()
}
}
}
impl Write for SHA512 {
#[inline(always)]
fn write(&mut self, b: &[u8]) -> std::io::Result<usize> {
self.update(b);
Ok(b.len())
}
#[inline(always)]
fn write(&mut self, b: &[u8]) -> std::io::Result<usize> {
self.update(b);
Ok(b.len())
}
#[inline(always)]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
unsafe impl Send for SHA512 {}
@ -77,213 +77,213 @@ unsafe impl Send for SHA512 {}
pub struct SHA384(ffi::SHA512_CTX);
impl SHA384 {
#[inline(always)]
pub fn hash(data: &[u8]) -> [u8; SHA384_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 48]>::uninit();
ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _);
hash.assume_init()
}
}
#[inline(always)]
pub fn hash(data: &[u8]) -> [u8; SHA384_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 48]>::uninit();
ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _);
hash.assume_init()
}
}
#[inline(always)]
pub fn new() -> Self {
unsafe {
let mut ctx = MaybeUninit::uninit();
ffi::SHA384_Init(ctx.as_mut_ptr());
SHA384(ctx.assume_init())
}
}
#[inline(always)]
pub fn new() -> Self {
unsafe {
let mut ctx = MaybeUninit::uninit();
ffi::SHA384_Init(ctx.as_mut_ptr());
SHA384(ctx.assume_init())
}
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
ffi::SHA384_Init(&mut self.0);
}
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
ffi::SHA384_Init(&mut self.0);
}
}
#[inline(always)]
pub fn update(&mut self, buf: &[u8]) {
unsafe {
ffi::SHA384_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
}
}
#[inline(always)]
pub fn update(&mut self, buf: &[u8]) {
unsafe {
ffi::SHA384_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len());
}
}
#[inline(always)]
pub fn finish(&mut self) -> [u8; SHA384_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 48]>::uninit();
ffi::SHA384_Final(hash.as_mut_ptr() as *mut _, &mut self.0);
hash.assume_init()
}
}
#[inline(always)]
pub fn finish(&mut self) -> [u8; SHA384_HASH_SIZE] {
unsafe {
let mut hash = MaybeUninit::<[u8; 48]>::uninit();
ffi::SHA384_Final(hash.as_mut_ptr() as *mut _, &mut self.0);
hash.assume_init()
}
}
}
impl Write for SHA384 {
#[inline(always)]
fn write(&mut self, b: &[u8]) -> std::io::Result<usize> {
self.update(b);
Ok(b.len())
}
#[inline(always)]
fn write(&mut self, b: &[u8]) -> std::io::Result<usize> {
self.update(b);
Ok(b.len())
}
#[inline(always)]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
unsafe impl Send for SHA384 {}
//#[link(name="crypto")]
extern "C" {
fn HMAC_CTX_new() -> *mut c_void;
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_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_CTX_free(ctx: *mut c_void);
fn EVP_sha384() -> *const c_void;
fn EVP_sha512() -> *const c_void;
fn HMAC_CTX_new() -> *mut c_void;
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_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_CTX_free(ctx: *mut c_void);
fn EVP_sha384() -> *const c_void;
fn EVP_sha512() -> *const c_void;
}
pub struct HMACSHA512 {
ctx: *mut c_void,
evp_md: *const c_void,
ctx: *mut c_void,
evp_md: *const c_void,
}
impl HMACSHA512 {
#[inline(always)]
pub fn new(key: &[u8]) -> Self {
unsafe {
let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha512() };
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);
hm
}
}
#[inline(always)]
pub fn new(key: &[u8]) -> Self {
unsafe {
let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha512() };
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);
hm
}
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
assert_ne!(HMAC_CTX_reset(self.ctx), 0);
}
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
assert_ne!(HMAC_CTX_reset(self.ctx), 0);
}
}
#[inline(always)]
pub fn update(&mut self, b: &[u8]) {
unsafe {
assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0);
}
}
#[inline(always)]
pub fn update(&mut self, b: &[u8]) {
unsafe {
assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0);
}
}
#[inline(always)]
pub fn finish_into(&mut self, md: &mut [u8]) {
unsafe {
assert_eq!(md.len(), 64);
let mut mdlen: c_uint = 64;
assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0);
assert_eq!(mdlen, 64);
}
}
#[inline(always)]
pub fn finish_into(&mut self, md: &mut [u8]) {
unsafe {
assert_eq!(md.len(), 64);
let mut mdlen: c_uint = 64;
assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0);
assert_eq!(mdlen, 64);
}
}
#[inline(always)]
pub fn finish(&mut self) -> [u8; 64] {
let mut tmp = [0u8; 64];
self.finish_into(&mut tmp);
tmp
}
#[inline(always)]
pub fn finish(&mut self) -> [u8; 64] {
let mut tmp = [0u8; 64];
self.finish_into(&mut tmp);
tmp
}
}
impl Drop for HMACSHA512 {
#[inline(always)]
fn drop(&mut self) {
unsafe { HMAC_CTX_free(self.ctx) };
}
#[inline(always)]
fn drop(&mut self) {
unsafe { HMAC_CTX_free(self.ctx) };
}
}
unsafe impl Send for HMACSHA512 {}
pub struct HMACSHA384 {
ctx: *mut c_void,
evp_md: *const c_void,
ctx: *mut c_void,
evp_md: *const c_void,
}
impl HMACSHA384 {
#[inline(always)]
pub fn new(key: &[u8]) -> Self {
unsafe {
let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha384() };
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);
hm
}
}
#[inline(always)]
pub fn new(key: &[u8]) -> Self {
unsafe {
let hm = Self { ctx: HMAC_CTX_new(), evp_md: EVP_sha384() };
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);
hm
}
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
assert_ne!(HMAC_CTX_reset(self.ctx), 0);
}
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
assert_ne!(HMAC_CTX_reset(self.ctx), 0);
}
}
#[inline(always)]
pub fn update(&mut self, b: &[u8]) {
unsafe {
assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0);
}
}
#[inline(always)]
pub fn update(&mut self, b: &[u8]) {
unsafe {
assert_ne!(HMAC_Update(self.ctx, b.as_ptr().cast(), b.len()), 0);
}
}
#[inline(always)]
pub fn finish_into(&mut self, md: &mut [u8]) {
unsafe {
assert_eq!(md.len(), 48);
let mut mdlen: c_uint = 48;
assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0);
assert_eq!(mdlen, 48);
}
}
#[inline(always)]
pub fn finish_into(&mut self, md: &mut [u8]) {
unsafe {
assert_eq!(md.len(), 48);
let mut mdlen: c_uint = 48;
assert_ne!(HMAC_Final(self.ctx, md.as_mut_ptr().cast(), &mut mdlen), 0);
assert_eq!(mdlen, 48);
}
}
#[inline(always)]
pub fn finish(&mut self) -> [u8; 48] {
let mut tmp = [0u8; 48];
self.finish_into(&mut tmp);
tmp
}
#[inline(always)]
pub fn finish(&mut self) -> [u8; 48] {
let mut tmp = [0u8; 48];
self.finish_into(&mut tmp);
tmp
}
}
impl Drop for HMACSHA384 {
#[inline(always)]
fn drop(&mut self) {
unsafe { HMAC_CTX_free(self.ctx) };
}
#[inline(always)]
fn drop(&mut self) {
unsafe { HMAC_CTX_free(self.ctx) };
}
}
unsafe impl Send for HMACSHA384 {}
#[inline(always)]
pub fn hmac_sha512(key: &[u8], msg: &[u8]) -> [u8; 64] {
let mut hm = HMACSHA512::new(key);
hm.update(msg);
hm.finish()
let mut hm = HMACSHA512::new(key);
hm.update(msg);
hm.finish()
}
#[inline(always)]
pub fn hmac_sha512_into(key: &[u8], msg: &[u8], md: &mut [u8]) {
let mut hm = HMACSHA512::new(key);
hm.update(msg);
hm.finish_into(md);
let mut hm = HMACSHA512::new(key);
hm.update(msg);
hm.finish_into(md);
}
#[inline(always)]
pub fn hmac_sha384(key: &[u8], msg: &[u8]) -> [u8; 48] {
let mut hm = HMACSHA384::new(key);
hm.update(msg);
hm.finish()
let mut hm = HMACSHA384::new(key);
hm.update(msg);
hm.finish()
}
#[inline(always)]
pub fn hmac_sha384_into(key: &[u8], msg: &[u8], md: &mut [u8]) {
let mut hm = HMACSHA384::new(key);
hm.update(msg);
hm.finish_into(md);
let mut hm = HMACSHA384::new(key);
hm.update(msg);
hm.finish_into(md);
}