#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
use core::ffi::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void};
pub type CpaStatus = c_int;
pub const CPA_STATUS_SUCCESS: CpaStatus = 0;
pub const CPA_STATUS_FAIL: CpaStatus = -1;
pub const CPA_STATUS_RETRY: CpaStatus = 1;
pub const CPA_STATUS_RESOURCE: CpaStatus = 2;
pub const CPA_STATUS_INVALID_PARAM: CpaStatus = 3;
pub const CPA_STATUS_FATAL: CpaStatus = -2;
pub const CPA_STATUS_UNSUPPORTED: CpaStatus = -3;
pub const CPA_STATUS_RESTARTING: CpaStatus = 4;
pub type CpaBoolean = c_uchar;
pub const CPA_FALSE: CpaBoolean = 0;
pub const CPA_TRUE: CpaBoolean = 1;
pub type CpaInstanceHandle = *mut c_void;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaFlatBuffer {
pub dataLenInBytes: u32,
pub pData: *mut u8,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaBufferList {
pub numBuffers: u32,
pub pPrivateMetaData: *mut c_void,
pub pBuffers: *mut CpaFlatBuffer,
}
pub type CpaPhysicalAddr = u64;
pub type CpaDcSessionHandle = *mut c_void;
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcCompType {
CPA_DC_DEFLATE = 0,
CPA_DC_LZ4 = 1,
CPA_DC_LZ4S = 2,
CPA_DC_ZSTD = 3,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcCompLvl {
CPA_DC_L1 = 1,
CPA_DC_L2 = 2,
CPA_DC_L3 = 3,
CPA_DC_L4 = 4,
CPA_DC_L5 = 5,
CPA_DC_L6 = 6,
CPA_DC_L7 = 7,
CPA_DC_L8 = 8,
CPA_DC_L9 = 9,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcHuffType {
CPA_DC_HT_STATIC = 0,
CPA_DC_HT_FULL_DYNAMIC = 1,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcSessionDir {
CPA_DC_DIR_COMPRESS = 0,
CPA_DC_DIR_DECOMPRESS = 1,
CPA_DC_DIR_COMBINED = 2,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcSessionState {
CPA_DC_STATEFUL = 0,
CPA_DC_STATELESS = 1,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcFlush {
CPA_DC_FLUSH_NONE = 0,
CPA_DC_FLUSH_FINAL = 1,
CPA_DC_FLUSH_SYNC = 2,
CPA_DC_FLUSH_FULL = 3,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcReqType {
CPA_DC_REQ_FIRST = 0,
CPA_DC_REQ_SUBSEQUENT = 1,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaDcChecksum {
CPA_DC_NONE = 0,
CPA_DC_CRC32 = 1,
CPA_DC_ADLER32 = 2,
CPA_DC_CRC32_ADLER32 = 3,
CPA_DC_XXHASH32 = 4,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaDcSessionSetupData {
pub compLevel: CpaDcCompLvl,
pub compType: CpaDcCompType,
pub huffType: CpaDcHuffType,
pub autoSelectBestHuffmanTree: CpaBoolean,
pub sessDirection: CpaDcSessionDir,
pub sessState: CpaDcSessionState,
pub checksum: CpaDcChecksum,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaDcOpData {
pub flushFlag: CpaDcFlush,
pub compressAndVerify: CpaBoolean,
pub compressAndVerifyAndRecover: CpaBoolean,
pub integrityCrcCheck: CpaBoolean,
pub reserved: u32,
pub inputSkipData: CpaFlatBuffer,
pub outputSkipData: CpaFlatBuffer,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaDcRqResults {
pub status: CpaStatus,
pub consumed: u32,
pub produced: u32,
pub crc32: u32,
pub adler32: u32,
pub checksum: u64,
}
#[repr(C)]
#[derive(Debug, Clone)]
pub struct CpaDcInstanceCapabilities {
pub compressAndVerify: CpaBoolean,
pub compressAndVerifyAndRecover: CpaBoolean,
pub batchAndPack: CpaBoolean,
pub integrityCrcs64b: CpaBoolean,
pub checksumCRC32: CpaBoolean,
pub checksumCRC64: CpaBoolean,
pub checksumAdler32: CpaBoolean,
pub checksumXXHash32: CpaBoolean,
pub dynamicHuffman: CpaBoolean,
pub precompiledHuffman: CpaBoolean,
pub autoSelectBestHuffmanTree: CpaBoolean,
pub validWindowSizes: [CpaBoolean; 32],
}
pub type CpaDcCallbackFn =
Option<unsafe extern "C" fn(callbackTag: *mut c_void, status: CpaStatus)>;
pub type CpaCySymSessionCtx = *mut c_void;
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaCySymOp {
CPA_CY_SYM_OP_CIPHER = 0,
CPA_CY_SYM_OP_HASH = 1,
CPA_CY_SYM_OP_ALGORITHM_CHAINING = 2,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaCySymCipherAlgorithm {
CPA_CY_SYM_CIPHER_NULL = 0,
CPA_CY_SYM_CIPHER_ARC4 = 1,
CPA_CY_SYM_CIPHER_AES_ECB = 2,
CPA_CY_SYM_CIPHER_AES_CBC = 3,
CPA_CY_SYM_CIPHER_AES_CTR = 4,
CPA_CY_SYM_CIPHER_AES_CCM = 5,
CPA_CY_SYM_CIPHER_AES_GCM = 6,
CPA_CY_SYM_CIPHER_AES_XTS = 7,
CPA_CY_SYM_CIPHER_CHACHA = 8,
CPA_CY_SYM_CIPHER_SM4_ECB = 9,
CPA_CY_SYM_CIPHER_SM4_CBC = 10,
CPA_CY_SYM_CIPHER_SM4_CTR = 11,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaCySymCipherDirection {
CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT = 0,
CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT = 1,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaCySymHashAlgorithm {
CPA_CY_SYM_HASH_NONE = 0,
CPA_CY_SYM_HASH_MD5 = 1,
CPA_CY_SYM_HASH_SHA1 = 2,
CPA_CY_SYM_HASH_SHA224 = 3,
CPA_CY_SYM_HASH_SHA256 = 4,
CPA_CY_SYM_HASH_SHA384 = 5,
CPA_CY_SYM_HASH_SHA512 = 6,
CPA_CY_SYM_HASH_AES_XCBC = 7,
CPA_CY_SYM_HASH_AES_CCM = 8,
CPA_CY_SYM_HASH_AES_GCM = 9,
CPA_CY_SYM_HASH_AES_CMAC = 10,
CPA_CY_SYM_HASH_AES_GMAC = 11,
CPA_CY_SYM_HASH_POLY = 12,
CPA_CY_SYM_HASH_SM3 = 13,
CPA_CY_SYM_HASH_SHA3_256 = 14,
CPA_CY_SYM_HASH_SHA3_384 = 15,
CPA_CY_SYM_HASH_SHA3_512 = 16,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaCySymHashMode {
CPA_CY_SYM_HASH_MODE_PLAIN = 0,
CPA_CY_SYM_HASH_MODE_AUTH = 1,
CPA_CY_SYM_HASH_MODE_NESTED = 2,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaCySymCipherSetupData {
pub cipherAlgorithm: CpaCySymCipherAlgorithm,
pub cipherKeyLenInBytes: u32,
pub pCipherKey: *const u8,
pub cipherDirection: CpaCySymCipherDirection,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaCySymHashSetupData {
pub hashAlgorithm: CpaCySymHashAlgorithm,
pub hashMode: CpaCySymHashMode,
pub digestResultLenInBytes: u32,
pub authModeSetupData: CpaCySymHashAuthModeSetupData,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaCySymHashAuthModeSetupData {
pub authKey: *const u8,
pub authKeyLenInBytes: u32,
pub aadLenInBytes: u32,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaCySymSessionSetupData {
pub sessionPriority: u32,
pub symOperation: CpaCySymOp,
pub cipherSetupData: CpaCySymCipherSetupData,
pub hashSetupData: CpaCySymHashSetupData,
pub algChainOrder: u32,
pub digestIsAppended: CpaBoolean,
pub verifyDigest: CpaBoolean,
pub partialsNotRequired: CpaBoolean,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CpaCySymOpData {
pub sessionCtx: CpaCySymSessionCtx,
pub packetType: u32,
pub pIv: *const u8,
pub ivLenInBytes: u32,
pub cryptoStartSrcOffsetInBytes: u32,
pub messageLenToCipherInBytes: u32,
pub hashStartSrcOffsetInBytes: u32,
pub messageLenToHashInBytes: u32,
pub pDigestResult: *mut u8,
pub pAdditionalAuthData: *const u8,
}
pub type CpaCySymCbFunc = Option<
unsafe extern "C" fn(
callbackTag: *mut c_void,
status: CpaStatus,
operationType: CpaCySymOp,
pOpData: *mut c_void,
pDstBuffer: *mut CpaBufferList,
verifyResult: CpaBoolean,
),
>;
#[cfg(feature = "qat")]
unsafe extern "C" {
pub fn icp_sal_userStartMultiProcess(
pProcessName: *const c_char,
limitDevAccess: CpaBoolean,
) -> CpaStatus;
pub fn icp_sal_userStop() -> CpaStatus;
pub fn icp_sal_userIsQatRunning() -> CpaBoolean;
}
#[cfg(feature = "qat")]
unsafe extern "C" {
pub fn cpaDcGetNumInstances(pNumInstances: *mut u16) -> CpaStatus;
pub fn cpaDcGetInstances(numInstances: u16, pInstances: *mut CpaInstanceHandle) -> CpaStatus;
pub fn cpaDcStartInstance(
instanceHandle: CpaInstanceHandle,
numConcurrentRequests: u16,
) -> CpaStatus;
pub fn cpaDcStopInstance(instanceHandle: CpaInstanceHandle) -> CpaStatus;
pub fn cpaDcQueryCapabilities(
instanceHandle: CpaInstanceHandle,
pInstanceCapabilities: *mut CpaDcInstanceCapabilities,
) -> CpaStatus;
pub fn cpaDcGetSessionSize(
instanceHandle: CpaInstanceHandle,
pSessionSetupData: *const CpaDcSessionSetupData,
pSessionSize: *mut u32,
pContextSize: *mut u32,
) -> CpaStatus;
pub fn cpaDcInitSession(
instanceHandle: CpaInstanceHandle,
pSessionHandle: CpaDcSessionHandle,
pSessionSetupData: *const CpaDcSessionSetupData,
pContextBuffer: *mut c_void,
dcCbFunc: CpaDcCallbackFn,
) -> CpaStatus;
pub fn cpaDcRemoveSession(
instanceHandle: CpaInstanceHandle,
pSessionHandle: CpaDcSessionHandle,
) -> CpaStatus;
pub fn cpaDcCompressData(
instanceHandle: CpaInstanceHandle,
pSessionHandle: CpaDcSessionHandle,
pSrcBuff: *const CpaBufferList,
pDestBuff: *mut CpaBufferList,
pResults: *mut CpaDcRqResults,
flushFlag: CpaDcFlush,
callbackTag: *mut c_void,
) -> CpaStatus;
pub fn cpaDcCompressData2(
instanceHandle: CpaInstanceHandle,
pSessionHandle: CpaDcSessionHandle,
pSrcBuff: *const CpaBufferList,
pDestBuff: *mut CpaBufferList,
pOpData: *const CpaDcOpData,
pResults: *mut CpaDcRqResults,
callbackTag: *mut c_void,
) -> CpaStatus;
pub fn cpaDcDecompressData(
instanceHandle: CpaInstanceHandle,
pSessionHandle: CpaDcSessionHandle,
pSrcBuff: *const CpaBufferList,
pDestBuff: *mut CpaBufferList,
pResults: *mut CpaDcRqResults,
flushFlag: CpaDcFlush,
callbackTag: *mut c_void,
) -> CpaStatus;
pub fn cpaDcDecompressData2(
instanceHandle: CpaInstanceHandle,
pSessionHandle: CpaDcSessionHandle,
pSrcBuff: *const CpaBufferList,
pDestBuff: *mut CpaBufferList,
pOpData: *const CpaDcOpData,
pResults: *mut CpaDcRqResults,
callbackTag: *mut c_void,
) -> CpaStatus;
pub fn icp_sal_DcPollInstance(
instanceHandle: CpaInstanceHandle,
response_quota: u32,
) -> CpaStatus;
}
#[cfg(feature = "qat")]
unsafe extern "C" {
pub fn cpaCyGetNumInstances(pNumInstances: *mut u16) -> CpaStatus;
pub fn cpaCyGetInstances(numInstances: u16, pInstances: *mut CpaInstanceHandle) -> CpaStatus;
pub fn cpaCyStartInstance(instanceHandle: CpaInstanceHandle) -> CpaStatus;
pub fn cpaCyStopInstance(instanceHandle: CpaInstanceHandle) -> CpaStatus;
pub fn cpaCySymSessionCtxGetSize(
instanceHandle: CpaInstanceHandle,
pSessionSetupData: *const CpaCySymSessionSetupData,
pSessionCtxSizeInBytes: *mut u32,
) -> CpaStatus;
pub fn cpaCySymInitSession(
instanceHandle: CpaInstanceHandle,
pSymCb: CpaCySymCbFunc,
pSessionSetupData: *const CpaCySymSessionSetupData,
sessionCtx: CpaCySymSessionCtx,
) -> CpaStatus;
pub fn cpaCySymRemoveSession(
instanceHandle: CpaInstanceHandle,
pSessionCtx: CpaCySymSessionCtx,
) -> CpaStatus;
pub fn cpaCySymPerformOp(
instanceHandle: CpaInstanceHandle,
callbackTag: *mut c_void,
pOpData: *const CpaCySymOpData,
pSrcBuffer: *const CpaBufferList,
pDstBuffer: *mut CpaBufferList,
pVerifyResult: *mut CpaBoolean,
) -> CpaStatus;
pub fn icp_sal_CyPollInstance(
instanceHandle: CpaInstanceHandle,
response_quota: u32,
) -> CpaStatus;
}
#[cfg(feature = "qat")]
unsafe extern "C" {
pub fn qaeMemAllocNUMA(size: usize, node: c_int, alignment: usize) -> *mut c_void;
pub fn qaeMemFreeNUMA(ptr: *mut *mut c_void);
pub fn qaeMemAlloc(size: usize) -> *mut c_void;
pub fn qaeMemFree(ptr: *mut *mut c_void);
pub fn qaeVirtToPhysNUMA(pVirtAddr: *mut c_void) -> CpaPhysicalAddr;
}
#[derive(Debug)]
pub struct QatInstance {
handle: CpaInstanceHandle,
is_dc: bool,
}
impl QatInstance {
pub unsafe fn new_dc(handle: CpaInstanceHandle) -> Self {
Self {
handle,
is_dc: true,
}
}
pub unsafe fn new_cy(handle: CpaInstanceHandle) -> Self {
Self {
handle,
is_dc: false,
}
}
pub fn handle(&self) -> CpaInstanceHandle {
self.handle
}
pub fn is_dc(&self) -> bool {
self.is_dc
}
}
#[cfg(feature = "qat")]
pub struct QatBuffer {
ptr: *mut u8,
size: usize,
node: i32,
}
#[cfg(feature = "qat")]
impl QatBuffer {
pub fn new(size: usize, node: i32) -> Option<Self> {
let ptr = unsafe { qaeMemAllocNUMA(size, node, 64) as *mut u8 };
if ptr.is_null() {
None
} else {
Some(Self { ptr, size, node })
}
}
pub fn as_ptr(&self) -> *mut u8 {
self.ptr
}
pub fn size(&self) -> usize {
self.size
}
pub fn phys_addr(&self) -> CpaPhysicalAddr {
unsafe { qaeVirtToPhysNUMA(self.ptr as *mut c_void) }
}
pub unsafe fn copy_from(&mut self, data: &[u8]) {
debug_assert!(data.len() <= self.size);
unsafe {
core::ptr::copy_nonoverlapping(data.as_ptr(), self.ptr, data.len());
}
}
pub unsafe fn copy_to(&self, dest: &mut [u8], len: usize) {
debug_assert!(len <= self.size);
debug_assert!(len <= dest.len());
unsafe {
core::ptr::copy_nonoverlapping(self.ptr, dest.as_mut_ptr(), len);
}
}
}
#[cfg(feature = "qat")]
impl Drop for QatBuffer {
fn drop(&mut self) {
unsafe {
let mut ptr = self.ptr as *mut c_void;
qaeMemFreeNUMA(&mut ptr);
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QatFfiError {
InitFailed,
NoInstances,
StartFailed,
SessionFailed,
MemoryError,
OperationFailed(CpaStatus),
NotRunning,
InvalidParam,
ResourceBusy,
}
impl QatFfiError {
pub fn from_status(status: CpaStatus) -> Result<(), Self> {
match status {
CPA_STATUS_SUCCESS => Ok(()),
CPA_STATUS_FAIL => Err(QatFfiError::OperationFailed(status)),
CPA_STATUS_RETRY => Err(QatFfiError::ResourceBusy),
CPA_STATUS_RESOURCE => Err(QatFfiError::ResourceBusy),
CPA_STATUS_INVALID_PARAM => Err(QatFfiError::InvalidParam),
CPA_STATUS_FATAL => Err(QatFfiError::OperationFailed(status)),
CPA_STATUS_UNSUPPORTED => Err(QatFfiError::OperationFailed(status)),
_ => Err(QatFfiError::OperationFailed(status)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cpa_status_constants() {
assert_eq!(CPA_STATUS_SUCCESS, 0);
assert_eq!(CPA_STATUS_FAIL, -1);
assert_eq!(CPA_STATUS_RETRY, 1);
}
#[test]
fn test_cpa_boolean_constants() {
assert_eq!(CPA_FALSE, 0);
assert_eq!(CPA_TRUE, 1);
}
#[test]
fn test_flat_buffer_size() {
assert_eq!(
core::mem::size_of::<CpaFlatBuffer>(),
core::mem::size_of::<u32>() + core::mem::size_of::<*mut u8>()
);
}
#[test]
fn test_compression_levels() {
assert_eq!(CpaDcCompLvl::CPA_DC_L1 as i32, 1);
assert_eq!(CpaDcCompLvl::CPA_DC_L9 as i32, 9);
}
#[test]
fn test_cipher_algorithms() {
assert_eq!(CpaCySymCipherAlgorithm::CPA_CY_SYM_CIPHER_AES_GCM as i32, 6);
assert_eq!(CpaCySymCipherAlgorithm::CPA_CY_SYM_CIPHER_AES_XTS as i32, 7);
assert_eq!(CpaCySymCipherAlgorithm::CPA_CY_SYM_CIPHER_CHACHA as i32, 8);
}
#[test]
fn test_hash_algorithms() {
assert_eq!(CpaCySymHashAlgorithm::CPA_CY_SYM_HASH_SHA256 as i32, 4);
assert_eq!(CpaCySymHashAlgorithm::CPA_CY_SYM_HASH_AES_GCM as i32, 9);
}
#[test]
fn test_error_conversion() {
assert!(QatFfiError::from_status(CPA_STATUS_SUCCESS).is_ok());
assert!(matches!(
QatFfiError::from_status(CPA_STATUS_FAIL),
Err(QatFfiError::OperationFailed(_))
));
assert!(matches!(
QatFfiError::from_status(CPA_STATUS_RETRY),
Err(QatFfiError::ResourceBusy)
));
}
#[test]
fn test_compression_types() {
assert_eq!(CpaDcCompType::CPA_DC_DEFLATE as i32, 0);
assert_eq!(CpaDcCompType::CPA_DC_LZ4 as i32, 1);
assert_eq!(CpaDcCompType::CPA_DC_ZSTD as i32, 3);
}
}