dpdk-fm10k/lib/librte_ipsec/crypto.h
Thomas Monjalon ef5baf3486 replace packed attributes
There is a common macro __rte_packed for packing structs,
which is now used where appropriate for consistency.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
2020-04-16 18:16:46 +02:00

183 lines
3.7 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018 Intel Corporation
*/
#ifndef _CRYPTO_H_
#define _CRYPTO_H_
/**
* @file crypto.h
* Contains crypto specific functions/structures/macros used internally
* by ipsec library.
*/
/*
* AES-CTR counter block format.
*/
struct aesctr_cnt_blk {
uint32_t nonce;
uint64_t iv;
uint32_t cnt;
} __rte_packed;
/*
* AES-GCM devices have some specific requirements for IV and AAD formats.
* Ideally that to be done by the driver itself.
*/
struct aead_gcm_iv {
uint32_t salt;
uint64_t iv;
uint32_t cnt;
} __rte_packed;
struct aead_gcm_aad {
uint32_t spi;
/*
* RFC 4106, section 5:
* Two formats of the AAD are defined:
* one for 32-bit sequence numbers, and one for 64-bit ESN.
*/
union {
uint32_t u32[2];
uint64_t u64;
} sqn;
uint32_t align0; /* align to 16B boundary */
} __rte_packed;
struct gcm_esph_iv {
struct rte_esp_hdr esph;
uint64_t iv;
} __rte_packed;
static inline void
aes_ctr_cnt_blk_fill(struct aesctr_cnt_blk *ctr, uint64_t iv, uint32_t nonce)
{
ctr->nonce = nonce;
ctr->iv = iv;
ctr->cnt = rte_cpu_to_be_32(1);
}
static inline void
aead_gcm_iv_fill(struct aead_gcm_iv *gcm, uint64_t iv, uint32_t salt)
{
gcm->salt = salt;
gcm->iv = iv;
gcm->cnt = rte_cpu_to_be_32(1);
}
/*
* RFC 4106, 5 AAD Construction
* spi and sqn should already be converted into network byte order.
* Make sure that not used bytes are zeroed.
*/
static inline void
aead_gcm_aad_fill(struct aead_gcm_aad *aad, rte_be32_t spi, rte_be64_t sqn,
int esn)
{
aad->spi = spi;
if (esn)
aad->sqn.u64 = sqn;
else {
aad->sqn.u32[0] = sqn_low32(sqn);
aad->sqn.u32[1] = 0;
}
aad->align0 = 0;
}
static inline void
gen_iv(uint64_t iv[IPSEC_MAX_IV_QWORD], rte_be64_t sqn)
{
iv[0] = sqn;
iv[1] = 0;
}
/*
* Helper routine to copy IV
* Right now we support only algorithms with IV length equals 0/8/16 bytes.
*/
static inline void
copy_iv(uint64_t dst[IPSEC_MAX_IV_QWORD],
const uint64_t src[IPSEC_MAX_IV_QWORD], uint32_t len)
{
RTE_BUILD_BUG_ON(IPSEC_MAX_IV_SIZE != 2 * sizeof(uint64_t));
switch (len) {
case IPSEC_MAX_IV_SIZE:
dst[1] = src[1];
/* fallthrough */
case sizeof(uint64_t):
dst[0] = src[0];
/* fallthrough */
case 0:
break;
default:
/* should never happen */
RTE_ASSERT(NULL);
}
}
/*
* from RFC 4303 3.3.2.1.4:
* If the ESN option is enabled for the SA, the high-order 32
* bits of the sequence number are appended after the Next Header field
* for purposes of this computation, but are not transmitted.
*/
/*
* Helper function that moves ICV by 4B below, and inserts SQN.hibits.
* icv parameter points to the new start of ICV.
*/
static inline void
insert_sqh(uint32_t sqh, void *picv, uint32_t icv_len)
{
uint32_t *icv;
int32_t i;
RTE_ASSERT(icv_len % sizeof(uint32_t) == 0);
icv = picv;
icv_len = icv_len / sizeof(uint32_t);
for (i = icv_len; i-- != 0; icv[i] = icv[i - 1])
;
icv[i] = sqh;
}
/*
* Helper function that moves ICV by 4B up, and removes SQN.hibits.
* icv parameter points to the new start of ICV.
*/
static inline void
remove_sqh(void *picv, uint32_t icv_len)
{
uint32_t i, *icv;
RTE_ASSERT(icv_len % sizeof(uint32_t) == 0);
icv = picv;
icv_len = icv_len / sizeof(uint32_t);
for (i = 0; i != icv_len; i++)
icv[i] = icv[i + 1];
}
/*
* setup crypto ops for LOOKASIDE_NONE (pure crypto) type of devices.
*/
static inline void
lksd_none_cop_prepare(struct rte_crypto_op *cop,
struct rte_cryptodev_sym_session *cs, struct rte_mbuf *mb)
{
struct rte_crypto_sym_op *sop;
sop = cop->sym;
cop->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
cop->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
sop->m_src = mb;
__rte_crypto_sym_op_attach_sym_session(sop, cs);
}
#endif /* _CRYPTO_H_ */