summaryrefslogtreecommitdiffstats
path: root/src/spdk/intel-ipsec-mb/intel-ipsec-mb.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/intel-ipsec-mb/intel-ipsec-mb.h')
-rw-r--r--src/spdk/intel-ipsec-mb/intel-ipsec-mb.h1419
1 files changed, 1419 insertions, 0 deletions
diff --git a/src/spdk/intel-ipsec-mb/intel-ipsec-mb.h b/src/spdk/intel-ipsec-mb/intel-ipsec-mb.h
new file mode 100644
index 00000000..09d5f079
--- /dev/null
+++ b/src/spdk/intel-ipsec-mb/intel-ipsec-mb.h
@@ -0,0 +1,1419 @@
+/*******************************************************************************
+ Copyright (c) 2012-2018, Intel Corporation
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Intel Corporation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+#ifndef IMB_IPSEC_MB_H
+#define IMB_IPSEC_MB_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 128-bit data type that is not in sdtint.h */
+typedef struct {
+ uint64_t low;
+ uint64_t high;
+} uint128_t;
+
+/*
+ * Macros for aligning data structures and function inlines
+ */
+#ifdef __linux__
+/* Linux */
+#define DECLARE_ALIGNED(decl, alignval) \
+ decl __attribute__((aligned(alignval)))
+#define __forceinline \
+ static inline __attribute__((always_inline))
+
+#if __GNUC__ >= 4
+#define IMB_DLL_EXPORT __attribute__((visibility("default")))
+#define IMB_DLL_LOCAL __attribute__((visibility("hidden")))
+#else /* GNU C 4.0 and later */
+#define IMB_DLL_EXPORT
+#define IMB_DLL_LOCAL
+#endif /* different C compiler */
+
+#else
+/* Windows */
+#define DECLARE_ALIGNED(decl, alignval) \
+ __declspec(align(alignval)) decl
+#define __forceinline \
+ static __forceinline
+
+/* Windows DLL export is done via DEF file */
+#define IMB_DLL_EXPORT
+#define IMB_DLL_LOCAL
+#endif
+
+/*
+ * Custom ASSERT and DIM macros
+ */
+#ifdef DEBUG
+#include <assert.h>
+#define IMB_ASSERT(x) assert(x)
+#else
+#define IMB_ASSERT(x)
+#endif
+
+#ifndef IMB_DIM
+#define IMB_DIM(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+/*
+ * Algorithm constants
+ */
+
+#define DES_KEY_SCHED_SIZE (16 * 8) /* 16 rounds x 8 bytes */
+#define DES_BLOCK_SIZE 8
+
+#define AES_BLOCK_SIZE 16
+
+#define NUM_MD5_DIGEST_WORDS 4
+#define NUM_SHA_DIGEST_WORDS 5
+#define NUM_SHA_256_DIGEST_WORDS 8
+#define NUM_SHA_224_DIGEST_WORDS 7
+#define NUM_SHA_512_DIGEST_WORDS 8
+#define NUM_SHA_384_DIGEST_WORDS 6
+
+#define SHA384_DIGEST_WORD_SIZE 8
+#define SHA512_DIGEST_WORD_SIZE 8
+
+#define SHA384_DIGEST_SIZE_IN_BYTES \
+ (NUM_SHA_384_DIGEST_WORDS * SHA384_DIGEST_WORD_SIZE)
+#define SHA512_DIGEST_SIZE_IN_BYTES \
+ (NUM_SHA_512_DIGEST_WORDS * SHA512_DIGEST_WORD_SIZE)
+
+#define SHA1_BLOCK_SIZE 64 /* 512 bits is 64 byte blocks */
+#define SHA_256_BLOCK_SIZE 64 /* 512 bits is 64 byte blocks */
+#define SHA_384_BLOCK_SIZE 128
+#define SHA_512_BLOCK_SIZE 128
+
+/* Number of lanes AVX512, AVX2, AVX and SSE */
+#define AVX512_NUM_SHA1_LANES 16
+#define AVX512_NUM_SHA256_LANES 16
+#define AVX512_NUM_SHA512_LANES 8
+#define AVX512_NUM_MD5_LANES 32
+#define AVX512_NUM_DES_LANES 16
+
+#define AVX2_NUM_SHA1_LANES 8
+#define AVX2_NUM_SHA256_LANES 8
+#define AVX2_NUM_SHA512_LANES 4
+#define AVX2_NUM_MD5_LANES 16
+
+#define AVX_NUM_SHA1_LANES 4
+#define AVX_NUM_SHA256_LANES 4
+#define AVX_NUM_SHA512_LANES 2
+#define AVX_NUM_MD5_LANES 8
+
+#define SSE_NUM_SHA1_LANES AVX_NUM_SHA1_LANES
+#define SSE_NUM_SHA256_LANES AVX_NUM_SHA256_LANES
+#define SSE_NUM_SHA512_LANES AVX_NUM_SHA512_LANES
+#define SSE_NUM_MD5_LANES AVX_NUM_MD5_LANES
+
+/*
+ * Each row is sized to hold enough lanes for AVX2, AVX1 and SSE use a subset
+ * of each row. Thus one row is not adjacent in memory to its neighboring rows
+ * in the case of SSE and AVX1.
+ */
+#define MD5_DIGEST_SZ (NUM_MD5_DIGEST_WORDS * AVX512_NUM_MD5_LANES)
+#define SHA1_DIGEST_SZ (NUM_SHA_DIGEST_WORDS * AVX512_NUM_SHA1_LANES)
+#define SHA256_DIGEST_SZ (NUM_SHA_256_DIGEST_WORDS * AVX512_NUM_SHA256_LANES)
+#define SHA512_DIGEST_SZ (NUM_SHA_512_DIGEST_WORDS * AVX512_NUM_SHA512_LANES)
+
+/*
+ * Job structure definitions
+ */
+
+typedef enum {
+ STS_BEING_PROCESSED = 0,
+ STS_COMPLETED_AES = 1,
+ STS_COMPLETED_HMAC = 2,
+ STS_COMPLETED = 3, /* COMPLETED_AES | COMPLETED_HMAC */
+ STS_INVALID_ARGS = 4,
+ STS_INTERNAL_ERROR,
+ STS_ERROR
+} JOB_STS;
+
+typedef enum {
+ CBC = 1,
+ CNTR,
+ NULL_CIPHER,
+ DOCSIS_SEC_BPI,
+#ifndef NO_GCM
+ GCM,
+#endif /* !NO_GCM */
+ CUSTOM_CIPHER,
+ DES,
+ DOCSIS_DES,
+ CCM,
+ DES3
+} JOB_CIPHER_MODE;
+
+typedef enum {
+ ENCRYPT = 1,
+ DECRYPT
+} JOB_CIPHER_DIRECTION;
+
+typedef enum {
+ SHA1 = 1,
+ SHA_224,
+ SHA_256,
+ SHA_384,
+ SHA_512,
+ AES_XCBC,
+ MD5,
+ NULL_HASH,
+#ifndef NO_GCM
+ AES_GMAC,
+#endif /* !NO_GCM */
+ CUSTOM_HASH,
+ AES_CCM,
+ AES_CMAC,
+} JOB_HASH_ALG;
+
+typedef enum {
+ CIPHER_HASH = 1,
+ HASH_CIPHER
+} JOB_CHAIN_ORDER;
+
+typedef enum {
+ AES_128_BYTES = 16,
+ AES_192_BYTES = 24,
+ AES_256_BYTES = 32
+} AES_KEY_SIZE_BYTES;
+
+typedef struct JOB_AES_HMAC {
+ /*
+ * For AES, aes_enc_key_expanded and aes_dec_key_expanded are
+ * expected to point to expanded keys structure.
+ * - AES-CTR and AES-CCM, only aes_enc_key_expanded is used
+ * - DOCSIS (AES-CBC + AES-CFB), both pointers are used
+ * aes_enc_key_expanded has to be set always for the partial block
+ *
+ * For DES, aes_enc_key_expanded and aes_dec_key_expanded are
+ * expected to point to DES key schedule.
+ * - same key schedule used for enc and dec operations
+ *
+ * For 3DES, aes_enc_key_expanded and aes_dec_key_expanded are
+ * expected to point to an array of 3 pointers for
+ * the corresponding 3 key schedules.
+ * - same key schedule used for enc and dec operations
+ */
+ const void *aes_enc_key_expanded; /* 16-byte aligned pointer. */
+ const void *aes_dec_key_expanded;
+ uint64_t aes_key_len_in_bytes; /* 16, 24 and 32 byte (128, 192 and
+ * 256-bit) keys supported */
+ const uint8_t *src; /* Input. May be cipher text or plaintext.
+ * In-place ciphering allowed. */
+ uint8_t *dst; /*Output. May be cipher text or plaintext.
+ * In-place ciphering allowed, i.e. dst = src. */
+ uint64_t cipher_start_src_offset_in_bytes;
+ uint64_t msg_len_to_cipher_in_bytes; /* Max len = 65472 bytes.
+ * IPSec case, the maximum cipher
+ * length would be:
+ * 65535 -
+ * 20 (outer IP header) -
+ * 24 (ESP header + IV) -
+ * 12 (supported ICV length) */
+ uint64_t hash_start_src_offset_in_bytes;
+ uint64_t msg_len_to_hash_in_bytes; /* Max len = 65496 bytes.
+ * (Max cipher len +
+ * 24 bytes ESP header) */
+ const uint8_t *iv; /* AES IV. */
+ uint64_t iv_len_in_bytes; /* AES IV length in bytes. */
+ uint8_t *auth_tag_output; /* HMAC Tag output. This may point to
+ * a location in the src buffer
+ * (for in place)*/
+ uint64_t auth_tag_output_len_in_bytes; /* Authentication (i.e. HMAC) tag
+ * output length in bytes
+ * (may be a truncated value) */
+
+ /* Start algorithm-specific fields */
+ union {
+ struct _HMAC_specific_fields {
+ /* Hashed result of HMAC key xor'd with ipad (0x36). */
+ const uint8_t *_hashed_auth_key_xor_ipad;
+ /* Hashed result of HMAC key xor'd with opad (0x5c). */
+ const uint8_t *_hashed_auth_key_xor_opad;
+ } HMAC;
+ struct _AES_XCBC_specific_fields {
+ /* 16-byte aligned pointers */
+ const uint32_t *_k1_expanded;
+ const uint8_t *_k2;
+ const uint8_t *_k3;
+ } XCBC;
+ struct _AES_CCM_specific_fields {
+ /* Additional Authentication Data (AAD) */
+ const void *aad;
+ uint64_t aad_len_in_bytes; /* Length of AAD */
+ } CCM;
+ struct _AES_CMAC_specific_fields {
+ const void *_key_expanded; /* 16-byte aligned */
+ const void *_skey1;
+ const void *_skey2;
+ } CMAC;
+#ifndef NO_GCM
+ struct _AES_GCM_specific_fields {
+ /* Additional Authentication Data (AAD) */
+ const void *aad;
+ uint64_t aad_len_in_bytes; /* Length of AAD */
+ } GCM;
+#endif /* !NO_GCM */
+ } u;
+
+ JOB_STS status;
+ JOB_CIPHER_MODE cipher_mode; /* CBC, CNTR, DES, GCM etc. */
+ JOB_CIPHER_DIRECTION cipher_direction; /* Encrypt/decrypt */
+ /* Ignored as the direction is implied by the chain _order field. */
+ JOB_HASH_ALG hash_alg; /* SHA-1 or others... */
+ JOB_CHAIN_ORDER chain_order; /* CIPHER_HASH or HASH_CIPHER */
+
+ void *user_data;
+ void *user_data2;
+
+ /*
+ * stateless custom cipher and hash
+ * Return:
+ * success: 0
+ * fail: other
+ */
+ int (*cipher_func)(struct JOB_AES_HMAC *);
+ int (*hash_func)(struct JOB_AES_HMAC *);
+} JOB_AES_HMAC;
+
+/*
+ * Argument structures for various algorithms
+ */
+typedef struct {
+ const uint8_t *in[8];
+ uint8_t *out[8];
+ const uint32_t *keys[8];
+ DECLARE_ALIGNED(uint128_t IV[8], 32);
+} AES_ARGS_x8;
+
+typedef struct {
+ DECLARE_ALIGNED(uint32_t digest[SHA1_DIGEST_SZ], 32);
+ uint8_t *data_ptr[AVX512_NUM_SHA1_LANES];
+} SHA1_ARGS;
+
+typedef struct {
+ DECLARE_ALIGNED(uint32_t digest[SHA256_DIGEST_SZ], 32);
+ uint8_t *data_ptr[AVX512_NUM_SHA256_LANES];
+} SHA256_ARGS;
+
+typedef struct {
+ DECLARE_ALIGNED(uint64_t digest[SHA512_DIGEST_SZ], 32);
+ uint8_t *data_ptr[AVX512_NUM_SHA512_LANES];
+} SHA512_ARGS;
+
+typedef struct {
+ DECLARE_ALIGNED(uint32_t digest[MD5_DIGEST_SZ], 32);
+ uint8_t *data_ptr[AVX512_NUM_MD5_LANES];
+} MD5_ARGS;
+
+typedef struct {
+ const uint8_t *in[8];
+ const uint32_t *keys[8];
+ DECLARE_ALIGNED(uint128_t ICV[8], 32);
+} AES_XCBC_ARGS_x8;
+
+typedef struct {
+ const uint8_t *in[AVX512_NUM_DES_LANES];
+ uint8_t *out[AVX512_NUM_DES_LANES];
+ const uint8_t *keys[AVX512_NUM_DES_LANES];
+ uint32_t IV[AVX512_NUM_DES_LANES * 2]; /* uint32_t is more handy here */
+ uint32_t partial_len[AVX512_NUM_DES_LANES];
+ uint32_t block_len[AVX512_NUM_DES_LANES];
+ const uint8_t *last_in[AVX512_NUM_DES_LANES];
+ uint8_t *last_out[AVX512_NUM_DES_LANES];
+} DES_ARGS_x16;
+
+/* AES out-of-order scheduler fields */
+typedef struct {
+ AES_ARGS_x8 args;
+ DECLARE_ALIGNED(uint16_t lens[8], 16);
+ /* each nibble is index (0...7) of an unused lane,
+ * the last nibble is set to F as a flag
+ */
+ uint64_t unused_lanes;
+ JOB_AES_HMAC *job_in_lane[8];
+} MB_MGR_AES_OOO;
+
+/* AES XCBC out-of-order scheduler fields */
+typedef struct {
+ DECLARE_ALIGNED(uint8_t final_block[2 * 16], 32);
+ JOB_AES_HMAC *job_in_lane;
+ uint64_t final_done;
+} XCBC_LANE_DATA;
+
+typedef struct {
+ AES_XCBC_ARGS_x8 args;
+ DECLARE_ALIGNED(uint16_t lens[8], 16);
+ /* each byte is index (0...3) of unused lanes
+ * byte 4 is set to FF as a flag
+ */
+ uint64_t unused_lanes;
+ XCBC_LANE_DATA ldata[8];
+} MB_MGR_AES_XCBC_OOO;
+
+/* AES-CCM out-of-order scheduler structure */
+typedef struct {
+ AES_ARGS_x8 args; /* need to re-use AES arguments */
+ DECLARE_ALIGNED(uint16_t lens[8], 16);
+ DECLARE_ALIGNED(uint16_t init_done[8], 16);
+ /* each byte is index (0...3) of unused lanes
+ * byte 4 is set to FF as a flag
+ */
+ uint64_t unused_lanes;
+ JOB_AES_HMAC *job_in_lane[8];
+ DECLARE_ALIGNED(uint8_t init_blocks[8 * (4 * 16)], 32);
+} MB_MGR_CCM_OOO;
+
+
+/* AES-CMAC out-of-order scheduler structure */
+typedef struct {
+ AES_ARGS_x8 args; /* need to re-use AES arguments */
+ DECLARE_ALIGNED(uint16_t lens[8], 16);
+ DECLARE_ALIGNED(uint16_t init_done[8], 16);
+ /* each byte is index (0...3) of unused lanes
+ * byte 4 is set to FF as a flag
+ */
+ uint64_t unused_lanes;
+ JOB_AES_HMAC *job_in_lane[8];
+ DECLARE_ALIGNED(uint8_t scratch[8 * 16], 32);
+} MB_MGR_CMAC_OOO;
+
+
+/* DES out-of-order scheduler fields */
+typedef struct {
+ DES_ARGS_x16 args;
+ DECLARE_ALIGNED(uint16_t lens[16], 16);
+ /* each nibble is index (0...7) of unused lanes
+ * nibble 8 is set to F as a flag
+ */
+ uint64_t unused_lanes;
+ JOB_AES_HMAC *job_in_lane[16];
+ uint32_t num_lanes_inuse;
+} MB_MGR_DES_OOO;
+
+
+/* HMAC-SHA1 and HMAC-SHA256/224 */
+typedef struct {
+ /* YMM aligned access to extra_block */
+ DECLARE_ALIGNED(uint8_t extra_block[2 * SHA1_BLOCK_SIZE+8], 32);
+ JOB_AES_HMAC *job_in_lane;
+ uint8_t outer_block[64];
+ uint32_t outer_done;
+ uint32_t extra_blocks; /* num extra blocks (1 or 2) */
+ uint32_t size_offset; /* offset in extra_block to start of
+ * size field */
+ uint32_t start_offset; /* offset to start of data */
+} HMAC_SHA1_LANE_DATA;
+
+/* HMAC-SHA512/384 */
+typedef struct {
+ DECLARE_ALIGNED(uint8_t extra_block[2 * SHA_512_BLOCK_SIZE + 16], 32);
+ uint8_t outer_block[SHA_512_BLOCK_SIZE];
+ JOB_AES_HMAC *job_in_lane;
+ uint32_t outer_done;
+ uint32_t extra_blocks; /* num extra blocks (1 or 2) */
+ uint32_t size_offset; /* offset in extra_block to start of
+ * size field */
+ uint32_t start_offset; /* offset to start of data */
+} HMAC_SHA512_LANE_DATA;
+
+/*
+ * unused_lanes contains a list of unused lanes stored as bytes or as
+ * nibbles depending on the arch. The end of list is either FF or F.
+ */
+typedef struct {
+ SHA1_ARGS args;
+ DECLARE_ALIGNED(uint16_t lens[16], 32);
+ uint64_t unused_lanes;
+ HMAC_SHA1_LANE_DATA ldata[AVX512_NUM_SHA1_LANES];
+ uint32_t num_lanes_inuse;
+} MB_MGR_HMAC_SHA_1_OOO;
+
+typedef struct {
+ SHA256_ARGS args;
+ DECLARE_ALIGNED(uint16_t lens[16], 16);
+ uint64_t unused_lanes;
+ HMAC_SHA1_LANE_DATA ldata[AVX512_NUM_SHA256_LANES];
+ uint32_t num_lanes_inuse;
+} MB_MGR_HMAC_SHA_256_OOO;
+
+typedef struct {
+ SHA512_ARGS args;
+ DECLARE_ALIGNED(uint16_t lens[8], 16);
+ uint64_t unused_lanes;
+ HMAC_SHA512_LANE_DATA ldata[AVX512_NUM_SHA512_LANES];
+} MB_MGR_HMAC_SHA_512_OOO;
+
+/* MD5-HMAC out-of-order scheduler fields */
+typedef struct {
+ MD5_ARGS args;
+ DECLARE_ALIGNED(uint16_t lens[AVX512_NUM_MD5_LANES], 16);
+ /*
+ * In the avx2 case, all 16 nibbles of unused lanes are used.
+ * In that case num_lanes_inuse is used to detect the end of the list
+ */
+ uint64_t unused_lanes;
+ HMAC_SHA1_LANE_DATA ldata[AVX512_NUM_MD5_LANES];
+ uint32_t num_lanes_inuse;
+} MB_MGR_HMAC_MD5_OOO;
+
+/* ========================================================================== */
+/* API data type definitions */
+struct MB_MGR;
+
+typedef void (*init_mb_mgr_t)(struct MB_MGR *);
+typedef JOB_AES_HMAC *(*get_next_job_t)(struct MB_MGR *);
+typedef JOB_AES_HMAC *(*submit_job_t)(struct MB_MGR *);
+typedef JOB_AES_HMAC *(*get_completed_job_t)(struct MB_MGR *);
+typedef JOB_AES_HMAC *(*flush_job_t)(struct MB_MGR *);
+typedef uint32_t (*queue_size_t)(struct MB_MGR *);
+typedef void (*keyexp_t)(const void *, void *, void *);
+typedef void (*cmac_subkey_gen_t)(const void *, void *, void *);
+typedef void (*hash_one_block_t)(const void *, void *);
+typedef void (*xcbc_keyexp_t)(const void *, void *, void *, void *);
+typedef int (*des_keysched_t)(uint64_t *, const void *);
+
+/* ========================================================================== */
+/* Multi-buffer manager flags passed to alloc_mb_mgr() */
+
+#define IMB_FLAG_SHANI_OFF (1ULL << 0) /* disable use of SHANI extension */
+
+/* ========================================================================== */
+/* Multi-buffer manager features - valid after call to init_mb_mgr() */
+
+#define IMB_FEATURE_SHANI (1ULL << 0) /* if set SHANI extensions is used */
+
+/* ========================================================================== */
+/* TOP LEVEL (MB_MGR) Data structure fields */
+
+#define MAX_JOBS 128
+
+typedef struct MB_MGR {
+ /*
+ * flags - passed to alloc_mb_mgr()
+ * features - reflects features of multi-buffer instance
+ */
+ uint64_t flags;
+ uint64_t features;
+
+ /*
+ * ARCH handlers / API
+ * Careful as changes here can break ABI compatibility
+ */
+ get_next_job_t get_next_job;
+ submit_job_t submit_job;
+ submit_job_t submit_job_nocheck;
+ get_completed_job_t get_completed_job;
+ flush_job_t flush_job;
+ queue_size_t queue_size;
+ keyexp_t keyexp_128;
+ keyexp_t keyexp_192;
+ keyexp_t keyexp_256;
+ cmac_subkey_gen_t cmac_subkey_gen_128;
+ xcbc_keyexp_t xcbc_keyexp;
+ des_keysched_t des_key_sched;
+ hash_one_block_t sha1_one_block;
+ hash_one_block_t sha224_one_block;
+ hash_one_block_t sha256_one_block;
+ hash_one_block_t sha384_one_block;
+ hash_one_block_t sha512_one_block;
+ hash_one_block_t md5_one_block;
+
+ /* in-order scheduler fields */
+ int earliest_job; /* byte offset, -1 if none */
+ int next_job; /* byte offset */
+ JOB_AES_HMAC jobs[MAX_JOBS];
+
+ /* out of order managers */
+ DECLARE_ALIGNED(MB_MGR_AES_OOO aes128_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_AES_OOO aes192_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_AES_OOO aes256_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_AES_OOO docsis_sec_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_DES_OOO des_enc_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_DES_OOO des_dec_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_DES_OOO des3_enc_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_DES_OOO des3_dec_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_DES_OOO docsis_des_enc_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_DES_OOO docsis_des_dec_ooo, 64);
+
+ DECLARE_ALIGNED(MB_MGR_HMAC_SHA_1_OOO hmac_sha_1_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_HMAC_SHA_256_OOO hmac_sha_224_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_HMAC_SHA_256_OOO hmac_sha_256_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_HMAC_SHA_512_OOO hmac_sha_384_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_HMAC_SHA_512_OOO hmac_sha_512_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_HMAC_MD5_OOO hmac_md5_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_AES_XCBC_OOO aes_xcbc_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_CCM_OOO aes_ccm_ooo, 64);
+ DECLARE_ALIGNED(MB_MGR_CMAC_OOO aes_cmac_ooo, 64);
+} MB_MGR;
+
+/* ========================================================================== */
+/* API definitions */
+
+/*
+ * get_next_job returns a job object. This must be filled in and returned
+ * via submit_job before get_next_job is called again.
+ * After submit_job is called, one should call get_completed_job() at least
+ * once (and preferably until it returns NULL).
+ * get_completed_job and flush_job returns a job object. This job object ceases
+ * to be usable at the next call to get_next_job
+ */
+IMB_DLL_EXPORT MB_MGR *alloc_mb_mgr(uint64_t flags);
+IMB_DLL_EXPORT void free_mb_mgr(MB_MGR *state);
+
+IMB_DLL_EXPORT void init_mb_mgr_avx(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_avx(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_nocheck_avx(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *flush_job_avx(MB_MGR *state);
+IMB_DLL_EXPORT uint32_t queue_size_avx(MB_MGR *state);
+
+IMB_DLL_EXPORT void init_mb_mgr_avx2(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_avx2(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_nocheck_avx2(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *flush_job_avx2(MB_MGR *state);
+IMB_DLL_EXPORT uint32_t queue_size_avx2(MB_MGR *state);
+
+IMB_DLL_EXPORT void init_mb_mgr_avx512(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_avx512(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_nocheck_avx512(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *flush_job_avx512(MB_MGR *state);
+IMB_DLL_EXPORT uint32_t queue_size_avx512(MB_MGR *state);
+
+IMB_DLL_EXPORT void init_mb_mgr_sse(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_sse(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *submit_job_nocheck_sse(MB_MGR *state);
+IMB_DLL_EXPORT JOB_AES_HMAC *flush_job_sse(MB_MGR *state);
+IMB_DLL_EXPORT uint32_t queue_size_sse(MB_MGR *state);
+
+#define get_completed_job_avx get_completed_job_sse
+#define get_next_job_avx get_next_job_sse
+
+#define get_completed_job_avx2 get_completed_job_sse
+#define get_next_job_avx2 get_next_job_sse
+
+#define get_completed_job_avx512 get_completed_job_sse
+#define get_next_job_avx512 get_next_job_sse
+
+/*
+ * JOBS() and ADV_JOBS() also used in mb_mgr_code.h
+ * index in JOBS array using byte offset rather than object index
+ */
+__forceinline
+JOB_AES_HMAC *JOBS(MB_MGR *state, const int offset)
+{
+ char *cp = (char *)state->jobs;
+
+ return (JOB_AES_HMAC *)(cp + offset);
+}
+
+__forceinline
+void ADV_JOBS(int *ptr)
+{
+ *ptr += sizeof(JOB_AES_HMAC);
+ if (*ptr >= (int) (MAX_JOBS * sizeof(JOB_AES_HMAC)))
+ *ptr = 0;
+}
+
+__forceinline
+JOB_AES_HMAC *
+get_completed_job_sse(MB_MGR *state)
+{
+ JOB_AES_HMAC *job;
+
+ if (state->earliest_job < 0)
+ return NULL;
+
+ job = JOBS(state, state->earliest_job);
+ if (job->status < STS_COMPLETED)
+ return NULL;
+
+ ADV_JOBS(&state->earliest_job);
+
+ if (state->earliest_job == state->next_job)
+ state->earliest_job = -1;
+
+ return job;
+}
+
+__forceinline
+JOB_AES_HMAC *
+get_next_job_sse(MB_MGR *state)
+{
+ return JOBS(state, state->next_job);
+}
+
+/*
+ * Wrapper macros to call arch API's set up
+ * at init phase of multi-buffer manager.
+ *
+ * For example, after calling init_mb_mgr_sse(&mgr)
+ * The 'mgr' structure be set up so that:
+ * mgr.get_next_job will point to get_next_job_sse(),
+ * mgr.submit_job will point to submit_job_sse(),
+ * mgr.submit_job_nocheck will point to submit_job_nocheck_sse(),
+ * mgr.get_completed_job will point to get_completed_job_sse(),
+ * mgr.flush_job will point to flush_job_sse(),
+ * mgr.queue_size will point to queue_size_sse()
+ * mgr.keyexp_128 will point to aes_keyexp_128_sse()
+ * mgr.keyexp_192 will point to aes_keyexp_192_sse()
+ * mgr.keyexp_256 will point to aes_keyexp_256_sse()
+ *
+ * Direct use of arch API's may result in better performance.
+ * Using below indirect interface may produce slightly worse performance but
+ * it can simplify application implementation.
+ * LibTestApp provides example of using the indirect interface.
+ */
+#define IMB_GET_NEXT_JOB(_mgr) ((_mgr)->get_next_job((_mgr)))
+#define IMB_SUBMIT_JOB(_mgr) ((_mgr)->submit_job((_mgr)))
+#define IMB_SUBMIT_JOB_NOCHECK(_mgr) ((_mgr)->submit_job_nocheck((_mgr)))
+#define IMB_GET_COMPLETED_JOB(_mgr) ((_mgr)->get_completed_job((_mgr)))
+#define IMB_FLUSH_JOB(_mgr) ((_mgr)->flush_job((_mgr)))
+#define IMB_QUEUE_SIZE(_mgr) ((_mgr)->queue_size((_mgr)))
+#define IMB_AES_KEYEXP_128(_mgr, _raw, _enc, _dec) \
+ ((_mgr)->keyexp_128((_raw), (_enc), (_dec)))
+#define IMB_AES_KEYEXP_192(_mgr, _raw, _enc, _dec) \
+ ((_mgr)->keyexp_192((_raw), (_enc), (_dec)))
+#define IMB_AES_KEYEXP_256(_mgr, _raw, _enc, _dec) \
+ ((_mgr)->keyexp_256((_raw), (_enc), (_dec)))
+#define IMB_AES_CMAC_SUBKEY_GEN_128(_mgr, _key_exp, _k1, _k2) \
+ ((_mgr)->cmac_subkey_gen_128((_key_exp), (_k1), (_k2)))
+#define IMB_AES_XCBC_KEYEXP(_mgr, _key, _k1_exp, _k2, _k3) \
+ ((_mgr)->xcbc_keyexp((_key), (_k1_exp), (_k2), (_k3)))
+#define IMB_DES_KEYSCHED(_mgr, _ks, _key) \
+ ((_mgr)->des_key_sched((_ks), (_key)))
+#define IMB_SHA1_ONE_BLOCK(_mgr, _data, _digest) \
+ ((_mgr)->sha1_one_block((_data), (_digest)))
+#define IMB_SHA224_ONE_BLOCK(_mgr, _data, _digest) \
+ ((_mgr)->sha224_one_block((_data), (_digest)))
+#define IMB_SHA256_ONE_BLOCK(_mgr, _data, _digest) \
+ ((_mgr)->sha256_one_block((_data), (_digest)))
+#define IMB_SHA384_ONE_BLOCK(_mgr, _data, _digest) \
+ ((_mgr)->sha384_one_block((_data), (_digest)))
+#define IMB_SHA512_ONE_BLOCK(_mgr, _data, _digest) \
+ ((_mgr)->sha512_one_block((_data), (_digest)))
+#define IMB_MD5_ONE_BLOCK(_mgr, _data, _digest) \
+ ((_mgr)->md5_one_block((_data), (_digest)))
+
+/* Auxiliary functions */
+
+/**
+ * @brief DES key schedule set up
+ *
+ * \a ks buffer needs to accomodate \a DES_KEY_SCHED_SIZE (128) bytes of data.
+ *
+ * @param ks destination buffer to accomodate DES key schedule
+ * @param key a pointer to an 8 byte DES key
+ *
+ * @return Operation status
+ * @retval 0 success
+ * @retval !0 error
+ */
+IMB_DLL_EXPORT int
+des_key_schedule(uint64_t *ks, const void *key);
+
+/* SSE */
+IMB_DLL_EXPORT void sha1_one_block_sse(const void *data, void *digest);
+IMB_DLL_EXPORT void sha224_one_block_sse(const void *data, void *digest);
+IMB_DLL_EXPORT void sha256_one_block_sse(const void *data, void *digest);
+IMB_DLL_EXPORT void sha384_one_block_sse(const void *data, void *digest);
+IMB_DLL_EXPORT void sha512_one_block_sse(const void *data, void *digest);
+IMB_DLL_EXPORT void md5_one_block_sse(const void *data, void *digest);
+IMB_DLL_EXPORT void aes_keyexp_128_sse(const void *key, void *enc_exp_keys,
+ void *dec_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_192_sse(const void *key, void *enc_exp_keys,
+ void *dec_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_256_sse(const void *key, void *enc_exp_keys,
+ void *dec_exp_keys);
+IMB_DLL_EXPORT void aes_xcbc_expand_key_sse(const void *key, void *k1_exp,
+ void *k2, void *k3);
+IMB_DLL_EXPORT void aes_keyexp_128_enc_sse(const void *key,
+ void *enc_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_192_enc_sse(const void *key,
+ void *enc_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_256_enc_sse(const void *key,
+ void *enc_exp_keys);
+IMB_DLL_EXPORT void aes_cmac_subkey_gen_sse(const void *key_exp, void *key1,
+ void *key2);
+IMB_DLL_EXPORT void aes_cfb_128_one_sse(void *out, const void *in,
+ const void *iv, const void *keys,
+ uint64_t len);
+/* AVX */
+IMB_DLL_EXPORT void sha1_one_block_avx(const void *data, void *digest);
+IMB_DLL_EXPORT void sha224_one_block_avx(const void *data, void *digest);
+IMB_DLL_EXPORT void sha256_one_block_avx(const void *data, void *digest);
+IMB_DLL_EXPORT void sha384_one_block_avx(const void *data, void *digest);
+IMB_DLL_EXPORT void sha512_one_block_avx(const void *data, void *digest);
+#define md5_one_block_avx md5_one_block_sse
+IMB_DLL_EXPORT void aes_keyexp_128_avx(const void *key, void *enc_exp_keys,
+ void *dec_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_192_avx(const void *key, void *enc_exp_keys,
+ void *dec_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_256_avx(const void *key, void *enc_exp_keys,
+ void *dec_exp_keys);
+IMB_DLL_EXPORT void aes_xcbc_expand_key_avx(const void *key, void *k1_exp,
+ void *k2, void *k3);
+IMB_DLL_EXPORT void aes_keyexp_128_enc_avx(const void *key,
+ void *enc_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_192_enc_avx(const void *key,
+ void *enc_exp_keys);
+IMB_DLL_EXPORT void aes_keyexp_256_enc_avx(const void *key,
+ void *enc_exp_keys);
+IMB_DLL_EXPORT void aes_cmac_subkey_gen_avx(const void *key_exp, void *key1,
+ void *key2);
+IMB_DLL_EXPORT void aes_cfb_128_one_avx(void *out, const void *in,
+ const void *iv, const void *keys,
+ uint64_t len);
+
+/* AVX2 */
+#define sha1_one_block_avx2 sha1_one_block_avx
+#define sha224_one_block_avx2 sha224_one_block_avx
+#define sha256_one_block_avx2 sha256_one_block_avx
+#define sha384_one_block_avx2 sha384_one_block_avx
+#define sha512_one_block_avx2 sha512_one_block_avx
+#define md5_one_block_avx2 md5_one_block_avx
+#define aes_keyexp_128_avx2 aes_keyexp_128_avx
+#define aes_keyexp_192_avx2 aes_keyexp_192_avx
+#define aes_keyexp_256_avx2 aes_keyexp_256_avx
+#define aes_xcbc_expand_key_avx2 aes_xcbc_expand_key_avx
+#define aes_keyexp_128_enc_avx2 aes_keyexp_128_enc_avx
+#define aes_keyexp_192_enc_avx2 aes_keyexp_192_enc_avx
+#define aes_keyexp_256_enc_avx2 aes_keyexp_256_enc_avx
+#define aes_cmac_subkey_gen_avx2 aes_cmac_subkey_gen_avx
+#define aes_cfb_128_one_avx2 aes_cfb_128_one_avx
+
+/* AVX512 */
+#define sha1_one_block_avx512 sha1_one_block_avx2
+#define sha224_one_block_avx512 sha224_one_block_avx2
+#define sha256_one_block_avx512 sha256_one_block_avx2
+#define sha384_one_block_avx512 sha384_one_block_avx2
+#define sha512_one_block_avx512 sha512_one_block_avx2
+#define md5_one_block_avx512 md5_one_block_avx2
+#define aes_keyexp_128_avx512 aes_keyexp_128_avx2
+#define aes_keyexp_192_avx512 aes_keyexp_192_avx2
+#define aes_keyexp_256_avx512 aes_keyexp_256_avx2
+#define aes_xcbc_expand_key_avx512 aes_xcbc_expand_key_avx2
+#define aes_keyexp_128_enc_avx512 aes_keyexp_128_enc_avx2
+#define aes_keyexp_192_enc_avx512 aes_keyexp_192_enc_avx2
+#define aes_keyexp_256_enc_avx512 aes_keyexp_256_enc_avx2
+#define aes_cmac_subkey_gen_avx512 aes_cmac_subkey_gen_avx2
+#define aes_cfb_128_one_avx512 aes_cfb_128_one_avx2
+
+/*
+ * Direct GCM API.
+ * Note that GCM is also availabe through job API.
+ */
+#ifndef NO_GCM
+/* Authenticated Tag Length in bytes.
+ * Valid values are 16 (most likely), 12 or 8. */
+#define MAX_TAG_LEN (16)
+/*
+ * IV data is limited to 16 bytes as follows:
+ * 12 bytes is provided by an application -
+ * pre-counter block j0: 4 byte salt (from Security Association)
+ * concatenated with 8 byte Initialization Vector (from IPSec ESP
+ * Payload).
+ * 4 byte value 0x00000001 is padded automatically by the library -
+ * there is no need to add these 4 bytes on application side anymore.
+ */
+#define GCM_IV_DATA_LEN (12)
+
+#define LONGEST_TESTED_AAD_LENGTH (2 * 1024)
+
+/* Key lengths of 128 and 256 supported */
+#define GCM_128_KEY_LEN (16)
+#define GCM_192_KEY_LEN (24)
+#define GCM_256_KEY_LEN (32)
+
+#define GCM_BLOCK_LEN 16
+#define GCM_ENC_KEY_LEN 16
+#define GCM_KEY_SETS (15) /*exp key + 14 exp round keys*/
+
+/**
+ * @brief holds intermediate key data needed to improve performance
+ *
+ * gcm_key_data hold internal key information used by gcm128, gcm192 and gcm256.
+ */
+#ifdef __WIN32
+__declspec(align(16))
+#endif /* WIN32 */
+struct gcm_key_data {
+ uint8_t expanded_keys[GCM_ENC_KEY_LEN * GCM_KEY_SETS];
+ /* storage for HashKey mod poly */
+ uint8_t shifted_hkey_1[GCM_ENC_KEY_LEN]; /* HashKey<<1 mod poly */
+ uint8_t shifted_hkey_2[GCM_ENC_KEY_LEN]; /* HashKey^2<<1 mod poly */
+ uint8_t shifted_hkey_3[GCM_ENC_KEY_LEN]; /* HashKey^3<<1 mod poly */
+ uint8_t shifted_hkey_4[GCM_ENC_KEY_LEN]; /* HashKey^4<<1 mod poly */
+ uint8_t shifted_hkey_5[GCM_ENC_KEY_LEN]; /* HashKey^5<<1 mod poly */
+ uint8_t shifted_hkey_6[GCM_ENC_KEY_LEN]; /* HashKey^6<<1 mod poly */
+ uint8_t shifted_hkey_7[GCM_ENC_KEY_LEN]; /* HashKey^7<<1 mod poly */
+ uint8_t shifted_hkey_8[GCM_ENC_KEY_LEN]; /* HashKey^8<<1 mod poly */
+ /*
+ * Storage for XOR of High 64 bits and low 64 bits of HashKey mod poly.
+ * This is needed for Karatsuba purposes.
+ */
+ uint8_t shifted_hkey_1_k[GCM_ENC_KEY_LEN]; /* HashKey<<1 mod poly */
+ uint8_t shifted_hkey_2_k[GCM_ENC_KEY_LEN]; /* HashKey^2<<1 mod poly */
+ uint8_t shifted_hkey_3_k[GCM_ENC_KEY_LEN]; /* HashKey^3<<1 mod poly */
+ uint8_t shifted_hkey_4_k[GCM_ENC_KEY_LEN]; /* HashKey^4<<1 mod poly */
+ uint8_t shifted_hkey_5_k[GCM_ENC_KEY_LEN]; /* HashKey^5<<1 mod poly */
+ uint8_t shifted_hkey_6_k[GCM_ENC_KEY_LEN]; /* HashKey^6<<1 mod poly */
+ uint8_t shifted_hkey_7_k[GCM_ENC_KEY_LEN]; /* HashKey^7<<1 mod poly */
+ uint8_t shifted_hkey_8_k[GCM_ENC_KEY_LEN]; /* HashKey^8<<1 mod poly */
+}
+#ifdef LINUX
+__attribute__((aligned(16)));
+#else
+;
+#endif
+
+/**
+ * @brief holds GCM operation context
+ */
+struct gcm_context_data {
+ /* init, update and finalize context data */
+ uint8_t aad_hash[GCM_BLOCK_LEN];
+ uint64_t aad_length;
+ uint64_t in_length;
+ uint8_t partial_block_enc_key[GCM_BLOCK_LEN];
+ uint8_t orig_IV[GCM_BLOCK_LEN];
+ uint8_t current_counter[GCM_BLOCK_LEN];
+ uint64_t partial_block_length;
+};
+
+/**
+ * @brief GCM-AES Encryption
+ *
+ * @param key_data GCM expanded key data
+ * @param context_data GCM operation context data
+ * @param out Ciphertext output. Encrypt in-place is allowed.
+ * @param in Plaintext input.
+ * @param len Length of data in Bytes for encryption.
+ * @param iv pointer to 12 byte IV structure. Internally, library
+ * concates 0x00000001 value to it.
+ * @param aad Additional Authentication Data (AAD).
+ * @param aad_len Length of AAD.
+ * @param auth_tag Authenticated Tag output.
+ * @param auth_tag_len Authenticated Tag Length in bytes (must be
+ * a multiple of 4 bytes). Valid values are
+ * 16 (most likely), 12 or 8.
+ */
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+/**
+ * @brief GCM-AES Decryption
+ *
+ * @param key_data GCM expanded keys data
+ * @param context_data GCM operation context data
+ * @param out Plaintext output. Decrypt in-place is allowed.
+ * @param in Ciphertext input.
+ * @param len Length of data in Bytes for decryption.
+ * @param iv pointer to 12 byte IV structure. Internally, library
+ * concates 0x00000001 value to it.
+ * @param aad Additional Authentication Data (AAD).
+ * @param aad_len Length of AAD.
+ * @param auth_tag Authenticated Tag output.
+ * @param auth_tag_len Authenticated Tag Length in bytes (must be
+ * a multiple of 4 bytes). Valid values are
+ * 16 (most likely), 12 or 8.
+ */
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, uint8_t const *in, uint64_t len,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+/**
+ * @brief Start a AES-GCM Encryption message
+ *
+ * @param key_data GCM expanded key data
+ * @param context_data GCM operation context data
+ * @param iv pointer to 12 byte IV structure. Internally, library
+ * concates 0x00000001 value to it.
+ * @param aad Additional Authentication Data (AAD).
+ * @param aad_len Length of AAD.
+ *
+ */
+IMB_DLL_EXPORT void
+aes_gcm_init_128_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len);
+IMB_DLL_EXPORT void
+aes_gcm_init_128_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len);
+IMB_DLL_EXPORT void
+aes_gcm_init_128_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_init_192_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len);
+IMB_DLL_EXPORT void
+aes_gcm_init_192_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len);
+IMB_DLL_EXPORT void
+aes_gcm_init_192_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_init_256_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv, uint8_t const *aad, uint64_t aad_len);
+IMB_DLL_EXPORT void
+aes_gcm_init_256_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len);
+IMB_DLL_EXPORT void
+aes_gcm_init_256_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ const uint8_t *iv,
+ uint8_t const *aad, uint64_t aad_len);
+
+/**
+ * @brief encrypt a block of a AES-GCM Encryption message
+ *
+ * @param key_data GCM expanded key data
+ * @param context_data GCM operation context data
+ * @param out Ciphertext output. Encrypt in-place is allowed.
+ * @param in Plaintext input.
+ * @param len Length of data in Bytes for decryption.
+ */
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_update_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_update_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_update_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_update_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_update_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_update_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_update_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_update_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_update_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+
+/**
+ * @brief decrypt a block of a AES-GCM Encryption message
+ *
+ * @param key_data GCM expanded key data
+ * @param context_data GCM operation context data
+ * @param out Plaintext output. Decrypt in-place is allowed.
+ * @param in Ciphertext input.
+ * @param len Length of data in Bytes for decryption.
+ */
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_update_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_update_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_update_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_update_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_update_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_update_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_update_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_update_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_update_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *out, const uint8_t *in, uint64_t len);
+
+/**
+ * @brief End encryption of a AES-GCM Encryption message
+ *
+ * @param key_data GCM expanded key data
+ * @param context_data GCM operation context data
+ * @param auth_tag Authenticated Tag output.
+ * @param auth_tag_len Authenticated Tag Length in bytes (must be
+ * a multiple of 4 bytes). Valid values are
+ * 16 (most likely), 12 or 8.
+ */
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_finalize_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_finalize_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_128_finalize_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_finalize_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_finalize_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_192_finalize_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_finalize_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_finalize_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_enc_256_finalize_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+/**
+ * @brief End decryption of a AES-GCM Encryption message
+ *
+ * @param key_data GCM expanded key data
+ * @param context_data GCM operation context data
+ * @param auth_tag Authenticated Tag output.
+ * @param auth_tag_len Authenticated Tag Length in bytes (must be
+ * a multiple of 4 bytes). Valid values are
+ * 16 (most likely), 12 or 8.
+ */
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_finalize_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_finalize_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_128_finalize_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_finalize_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_finalize_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_192_finalize_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_finalize_sse(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_finalize_avx_gen2(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+IMB_DLL_EXPORT void
+aes_gcm_dec_256_finalize_avx_gen4(const struct gcm_key_data *key_data,
+ struct gcm_context_data *context_data,
+ uint8_t *auth_tag, uint64_t auth_tag_len);
+
+/**
+ * @brief Precomputation of HashKey constants
+ *
+ * Precomputation of HashKey<<1 mod poly constants (shifted_hkey_X and
+ * shifted_hkey_X_k).
+ *
+ * @param gdata GCM context data
+ */
+IMB_DLL_EXPORT void aes_gcm_precomp_128_sse(struct gcm_key_data *key_data);
+IMB_DLL_EXPORT void aes_gcm_precomp_128_avx_gen2(struct gcm_key_data *key_data);
+IMB_DLL_EXPORT void aes_gcm_precomp_128_avx_gen4(struct gcm_key_data *key_data);
+
+IMB_DLL_EXPORT void aes_gcm_precomp_192_sse(struct gcm_key_data *key_data);
+IMB_DLL_EXPORT void aes_gcm_precomp_192_avx_gen2(struct gcm_key_data *key_data);
+IMB_DLL_EXPORT void aes_gcm_precomp_192_avx_gen4(struct gcm_key_data *key_data);
+
+IMB_DLL_EXPORT void aes_gcm_precomp_256_sse(struct gcm_key_data *key_data);
+IMB_DLL_EXPORT void aes_gcm_precomp_256_avx_gen2(struct gcm_key_data *key_data);
+IMB_DLL_EXPORT void aes_gcm_precomp_256_avx_gen4(struct gcm_key_data *key_data);
+
+/**
+ * @brief Pre-processes GCM key data
+ *
+ * Prefills the gcm key data with key values for each round and
+ * the initial sub hash key for tag encoding
+ *
+ * @param key pointer to key data
+ * @param key_data GCM expanded key data
+ *
+ */
+__forceinline
+void aes_gcm_pre_128_sse(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_128_enc_sse(key, key_data->expanded_keys);
+ aes_gcm_precomp_128_sse(key_data);
+}
+__forceinline
+void aes_gcm_pre_128_avx_gen2(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_128_enc_avx(key, key_data->expanded_keys);
+ aes_gcm_precomp_128_avx_gen2(key_data);
+}
+__forceinline
+void aes_gcm_pre_128_avx_gen4(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_128_enc_avx2(key, key_data->expanded_keys);
+ aes_gcm_precomp_128_avx_gen4(key_data);
+}
+
+__forceinline
+void aes_gcm_pre_192_sse(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_192_enc_sse(key, key_data->expanded_keys);
+ aes_gcm_precomp_192_sse(key_data);
+}
+__forceinline
+void aes_gcm_pre_192_avx_gen2(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_192_enc_avx(key, key_data->expanded_keys);
+ aes_gcm_precomp_192_avx_gen2(key_data);
+}
+__forceinline
+void aes_gcm_pre_192_avx_gen4(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_192_enc_avx2(key, key_data->expanded_keys);
+ aes_gcm_precomp_192_avx_gen4(key_data);
+}
+
+__forceinline
+void aes_gcm_pre_256_sse(const void *key, struct gcm_key_data *key_data)
+{
+ struct gcm_key_data tmp;
+
+ aes_keyexp_256_sse(key, key_data->expanded_keys, tmp.expanded_keys);
+ aes_gcm_precomp_256_sse(key_data);
+}
+__forceinline
+void aes_gcm_pre_256_avx_gen2(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_256_enc_avx(key, key_data->expanded_keys);
+ aes_gcm_precomp_256_avx_gen2(key_data);
+}
+__forceinline
+void aes_gcm_pre_256_avx_gen4(const void *key, struct gcm_key_data *key_data)
+{
+ aes_keyexp_256_enc_avx2(key, key_data->expanded_keys);
+ aes_gcm_precomp_256_avx_gen4(key_data);
+}
+#endif /* !NO_GCM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IMB_IPSEC_MB_H */