mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-22 22:33:58 -07:00
changed indentation to spaces
This commit is contained in:
parent
3775996078
commit
29b0800798
3 changed files with 3559 additions and 3559 deletions
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue