199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2018 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _CRYPTO_H_ 699a2dd95SBruce Richardson #define _CRYPTO_H_ 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson /** 999a2dd95SBruce Richardson * @file crypto.h 1099a2dd95SBruce Richardson * Contains crypto specific functions/structures/macros used internally 1199a2dd95SBruce Richardson * by ipsec library. 1299a2dd95SBruce Richardson */ 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson /* 1599a2dd95SBruce Richardson * AES-CTR counter block format. 1699a2dd95SBruce Richardson */ 1799a2dd95SBruce Richardson 18*fba98755SAndre Muezerie struct __rte_packed_begin aesctr_cnt_blk { 1999a2dd95SBruce Richardson uint32_t nonce; 2099a2dd95SBruce Richardson uint64_t iv; 2199a2dd95SBruce Richardson uint32_t cnt; 22*fba98755SAndre Muezerie } __rte_packed_end; 2399a2dd95SBruce Richardson 2499a2dd95SBruce Richardson /* 25c99d2619SRadu Nicolau * CHACHA20-POLY1305 devices have some specific requirements 26c99d2619SRadu Nicolau * for IV and AAD formats. 27c99d2619SRadu Nicolau * Ideally that to be done by the driver itself. 28c99d2619SRadu Nicolau */ 29c99d2619SRadu Nicolau 30*fba98755SAndre Muezerie struct __rte_packed_begin aead_chacha20_poly1305_iv { 31c99d2619SRadu Nicolau uint32_t salt; 32c99d2619SRadu Nicolau uint64_t iv; 33c99d2619SRadu Nicolau uint32_t cnt; 34*fba98755SAndre Muezerie } __rte_packed_end; 35c99d2619SRadu Nicolau 36*fba98755SAndre Muezerie struct __rte_packed_begin aead_chacha20_poly1305_aad { 37c99d2619SRadu Nicolau uint32_t spi; 38c99d2619SRadu Nicolau /* 39c99d2619SRadu Nicolau * RFC 4106, section 5: 40c99d2619SRadu Nicolau * Two formats of the AAD are defined: 41c99d2619SRadu Nicolau * one for 32-bit sequence numbers, and one for 64-bit ESN. 42c99d2619SRadu Nicolau */ 43c99d2619SRadu Nicolau union { 44c99d2619SRadu Nicolau uint32_t u32[2]; 45c99d2619SRadu Nicolau uint64_t u64; 46c99d2619SRadu Nicolau } sqn; 47c99d2619SRadu Nicolau uint32_t align0; /* align to 16B boundary */ 48*fba98755SAndre Muezerie } __rte_packed_end; 49c99d2619SRadu Nicolau 50*fba98755SAndre Muezerie struct __rte_packed_begin chacha20_poly1305_esph_iv { 51c99d2619SRadu Nicolau struct rte_esp_hdr esph; 52c99d2619SRadu Nicolau uint64_t iv; 53*fba98755SAndre Muezerie } __rte_packed_end; 54c99d2619SRadu Nicolau 55c99d2619SRadu Nicolau /* 5699a2dd95SBruce Richardson * AES-GCM devices have some specific requirements for IV and AAD formats. 5799a2dd95SBruce Richardson * Ideally that to be done by the driver itself. 5899a2dd95SBruce Richardson */ 5999a2dd95SBruce Richardson 60*fba98755SAndre Muezerie struct __rte_packed_begin aead_gcm_iv { 6199a2dd95SBruce Richardson uint32_t salt; 6299a2dd95SBruce Richardson uint64_t iv; 6399a2dd95SBruce Richardson uint32_t cnt; 64*fba98755SAndre Muezerie } __rte_packed_end; 6599a2dd95SBruce Richardson 66*fba98755SAndre Muezerie struct __rte_packed_begin aead_gcm_aad { 6799a2dd95SBruce Richardson uint32_t spi; 6899a2dd95SBruce Richardson /* 6999a2dd95SBruce Richardson * RFC 4106, section 5: 7099a2dd95SBruce Richardson * Two formats of the AAD are defined: 7199a2dd95SBruce Richardson * one for 32-bit sequence numbers, and one for 64-bit ESN. 7299a2dd95SBruce Richardson */ 7399a2dd95SBruce Richardson union { 7499a2dd95SBruce Richardson uint32_t u32[2]; 7599a2dd95SBruce Richardson uint64_t u64; 7699a2dd95SBruce Richardson } sqn; 7799a2dd95SBruce Richardson uint32_t align0; /* align to 16B boundary */ 78*fba98755SAndre Muezerie } __rte_packed_end; 7999a2dd95SBruce Richardson 80*fba98755SAndre Muezerie struct __rte_packed_begin gcm_esph_iv { 8199a2dd95SBruce Richardson struct rte_esp_hdr esph; 8299a2dd95SBruce Richardson uint64_t iv; 83*fba98755SAndre Muezerie } __rte_packed_end; 8499a2dd95SBruce Richardson 85c99d2619SRadu Nicolau /* 86c99d2619SRadu Nicolau * AES-CCM devices have some specific requirements for IV and AAD formats. 87c99d2619SRadu Nicolau * Ideally that to be done by the driver itself. 88c99d2619SRadu Nicolau */ 89*fba98755SAndre Muezerie union __rte_packed_begin aead_ccm_salt { 90c99d2619SRadu Nicolau uint32_t salt; 91c99d2619SRadu Nicolau struct inner { 92c99d2619SRadu Nicolau uint8_t salt8[3]; 93c99d2619SRadu Nicolau uint8_t ccm_flags; 94c99d2619SRadu Nicolau } inner; 95*fba98755SAndre Muezerie } __rte_packed_end; 96c99d2619SRadu Nicolau 97c99d2619SRadu Nicolau 98*fba98755SAndre Muezerie struct __rte_packed_begin aead_ccm_iv { 99c99d2619SRadu Nicolau uint8_t ccm_flags; 100c99d2619SRadu Nicolau uint8_t salt[3]; 101c99d2619SRadu Nicolau uint64_t iv; 102c99d2619SRadu Nicolau uint32_t cnt; 103*fba98755SAndre Muezerie } __rte_packed_end; 104c99d2619SRadu Nicolau 105*fba98755SAndre Muezerie struct __rte_packed_begin aead_ccm_aad { 106c99d2619SRadu Nicolau uint8_t padding[18]; 107c99d2619SRadu Nicolau uint32_t spi; 108c99d2619SRadu Nicolau /* 109c99d2619SRadu Nicolau * RFC 4309, section 5: 110c99d2619SRadu Nicolau * Two formats of the AAD are defined: 111c99d2619SRadu Nicolau * one for 32-bit sequence numbers, and one for 64-bit ESN. 112c99d2619SRadu Nicolau */ 113c99d2619SRadu Nicolau union { 114c99d2619SRadu Nicolau uint32_t u32[2]; 115c99d2619SRadu Nicolau uint64_t u64; 116c99d2619SRadu Nicolau } sqn; 117c99d2619SRadu Nicolau uint32_t align0; /* align to 16B boundary */ 118*fba98755SAndre Muezerie } __rte_packed_end; 119c99d2619SRadu Nicolau 120*fba98755SAndre Muezerie struct __rte_packed_begin ccm_esph_iv { 121c99d2619SRadu Nicolau struct rte_esp_hdr esph; 122c99d2619SRadu Nicolau uint64_t iv; 123*fba98755SAndre Muezerie } __rte_packed_end; 124c99d2619SRadu Nicolau 125c99d2619SRadu Nicolau 12699a2dd95SBruce Richardson static inline void 12799a2dd95SBruce Richardson aes_ctr_cnt_blk_fill(struct aesctr_cnt_blk *ctr, uint64_t iv, uint32_t nonce) 12899a2dd95SBruce Richardson { 12999a2dd95SBruce Richardson ctr->nonce = nonce; 13099a2dd95SBruce Richardson ctr->iv = iv; 13199a2dd95SBruce Richardson ctr->cnt = rte_cpu_to_be_32(1); 13299a2dd95SBruce Richardson } 13399a2dd95SBruce Richardson 13499a2dd95SBruce Richardson static inline void 135c99d2619SRadu Nicolau aead_chacha20_poly1305_iv_fill(struct aead_chacha20_poly1305_iv 136c99d2619SRadu Nicolau *chacha20_poly1305, 137c99d2619SRadu Nicolau uint64_t iv, uint32_t salt) 138c99d2619SRadu Nicolau { 139c99d2619SRadu Nicolau chacha20_poly1305->salt = salt; 140c99d2619SRadu Nicolau chacha20_poly1305->iv = iv; 141c99d2619SRadu Nicolau chacha20_poly1305->cnt = rte_cpu_to_be_32(1); 142c99d2619SRadu Nicolau } 143c99d2619SRadu Nicolau 144c99d2619SRadu Nicolau static inline void 14599a2dd95SBruce Richardson aead_gcm_iv_fill(struct aead_gcm_iv *gcm, uint64_t iv, uint32_t salt) 14699a2dd95SBruce Richardson { 14799a2dd95SBruce Richardson gcm->salt = salt; 14899a2dd95SBruce Richardson gcm->iv = iv; 14999a2dd95SBruce Richardson gcm->cnt = rte_cpu_to_be_32(1); 15099a2dd95SBruce Richardson } 15199a2dd95SBruce Richardson 152c99d2619SRadu Nicolau static inline void 153c99d2619SRadu Nicolau aead_ccm_iv_fill(struct aead_ccm_iv *ccm, uint64_t iv, uint32_t salt) 154c99d2619SRadu Nicolau { 155c99d2619SRadu Nicolau union aead_ccm_salt tsalt; 156c99d2619SRadu Nicolau 157c99d2619SRadu Nicolau tsalt.salt = salt; 158c99d2619SRadu Nicolau ccm->ccm_flags = tsalt.inner.ccm_flags; 159c99d2619SRadu Nicolau ccm->salt[0] = tsalt.inner.salt8[0]; 160c99d2619SRadu Nicolau ccm->salt[1] = tsalt.inner.salt8[1]; 161c99d2619SRadu Nicolau ccm->salt[2] = tsalt.inner.salt8[2]; 162c99d2619SRadu Nicolau ccm->iv = iv; 163c99d2619SRadu Nicolau ccm->cnt = rte_cpu_to_be_32(1); 164c99d2619SRadu Nicolau } 165c99d2619SRadu Nicolau 166c99d2619SRadu Nicolau 16799a2dd95SBruce Richardson /* 16899a2dd95SBruce Richardson * RFC 4106, 5 AAD Construction 16999a2dd95SBruce Richardson * spi and sqn should already be converted into network byte order. 17099a2dd95SBruce Richardson * Make sure that not used bytes are zeroed. 17199a2dd95SBruce Richardson */ 17299a2dd95SBruce Richardson static inline void 17399a2dd95SBruce Richardson aead_gcm_aad_fill(struct aead_gcm_aad *aad, rte_be32_t spi, rte_be64_t sqn, 17499a2dd95SBruce Richardson int esn) 17599a2dd95SBruce Richardson { 17699a2dd95SBruce Richardson aad->spi = spi; 17799a2dd95SBruce Richardson if (esn) 17899a2dd95SBruce Richardson aad->sqn.u64 = sqn; 17999a2dd95SBruce Richardson else { 18099a2dd95SBruce Richardson aad->sqn.u32[0] = sqn_low32(sqn); 18199a2dd95SBruce Richardson aad->sqn.u32[1] = 0; 18299a2dd95SBruce Richardson } 18399a2dd95SBruce Richardson aad->align0 = 0; 18499a2dd95SBruce Richardson } 18599a2dd95SBruce Richardson 186c99d2619SRadu Nicolau /* 187c99d2619SRadu Nicolau * RFC 4309, 5 AAD Construction 188c99d2619SRadu Nicolau * spi and sqn should already be converted into network byte order. 189c99d2619SRadu Nicolau * Make sure that not used bytes are zeroed. 190c99d2619SRadu Nicolau */ 191c99d2619SRadu Nicolau static inline void 192c99d2619SRadu Nicolau aead_ccm_aad_fill(struct aead_ccm_aad *aad, rte_be32_t spi, rte_be64_t sqn, 193c99d2619SRadu Nicolau int esn) 194c99d2619SRadu Nicolau { 195c99d2619SRadu Nicolau aad->spi = spi; 196c99d2619SRadu Nicolau if (esn) 197c99d2619SRadu Nicolau aad->sqn.u64 = sqn; 198c99d2619SRadu Nicolau else { 199c99d2619SRadu Nicolau aad->sqn.u32[0] = sqn_low32(sqn); 200c99d2619SRadu Nicolau aad->sqn.u32[1] = 0; 201c99d2619SRadu Nicolau } 202c99d2619SRadu Nicolau aad->align0 = 0; 203c99d2619SRadu Nicolau } 204c99d2619SRadu Nicolau 20599a2dd95SBruce Richardson static inline void 20699a2dd95SBruce Richardson gen_iv(uint64_t iv[IPSEC_MAX_IV_QWORD], rte_be64_t sqn) 20799a2dd95SBruce Richardson { 20899a2dd95SBruce Richardson iv[0] = sqn; 20999a2dd95SBruce Richardson iv[1] = 0; 21099a2dd95SBruce Richardson } 21199a2dd95SBruce Richardson 212c99d2619SRadu Nicolau 213c99d2619SRadu Nicolau /* 214c99d2619SRadu Nicolau * RFC 7634, 2.1 AAD Construction 215c99d2619SRadu Nicolau * spi and sqn should already be converted into network byte order. 216c99d2619SRadu Nicolau * Make sure that not used bytes are zeroed. 217c99d2619SRadu Nicolau */ 218c99d2619SRadu Nicolau static inline void 219c99d2619SRadu Nicolau aead_chacha20_poly1305_aad_fill(struct aead_chacha20_poly1305_aad *aad, 220c99d2619SRadu Nicolau rte_be32_t spi, rte_be64_t sqn, 221c99d2619SRadu Nicolau int esn) 222c99d2619SRadu Nicolau { 223c99d2619SRadu Nicolau aad->spi = spi; 224c99d2619SRadu Nicolau if (esn) 225c99d2619SRadu Nicolau aad->sqn.u64 = sqn; 226c99d2619SRadu Nicolau else { 227c99d2619SRadu Nicolau aad->sqn.u32[0] = sqn_low32(sqn); 228c99d2619SRadu Nicolau aad->sqn.u32[1] = 0; 229c99d2619SRadu Nicolau } 230c99d2619SRadu Nicolau aad->align0 = 0; 231c99d2619SRadu Nicolau } 232c99d2619SRadu Nicolau 23399a2dd95SBruce Richardson /* 23499a2dd95SBruce Richardson * Helper routine to copy IV 23599a2dd95SBruce Richardson * Right now we support only algorithms with IV length equals 0/8/16 bytes. 23699a2dd95SBruce Richardson */ 23799a2dd95SBruce Richardson static inline void 23899a2dd95SBruce Richardson copy_iv(uint64_t dst[IPSEC_MAX_IV_QWORD], 23999a2dd95SBruce Richardson const uint64_t src[IPSEC_MAX_IV_QWORD], uint32_t len) 24099a2dd95SBruce Richardson { 24199a2dd95SBruce Richardson RTE_BUILD_BUG_ON(IPSEC_MAX_IV_SIZE != 2 * sizeof(uint64_t)); 24299a2dd95SBruce Richardson 24399a2dd95SBruce Richardson switch (len) { 24499a2dd95SBruce Richardson case IPSEC_MAX_IV_SIZE: 24599a2dd95SBruce Richardson dst[1] = src[1]; 24699a2dd95SBruce Richardson /* fallthrough */ 24799a2dd95SBruce Richardson case sizeof(uint64_t): 24899a2dd95SBruce Richardson dst[0] = src[0]; 24999a2dd95SBruce Richardson /* fallthrough */ 25099a2dd95SBruce Richardson case 0: 25199a2dd95SBruce Richardson break; 25299a2dd95SBruce Richardson default: 25399a2dd95SBruce Richardson /* should never happen */ 25499a2dd95SBruce Richardson RTE_ASSERT(NULL); 25599a2dd95SBruce Richardson } 25699a2dd95SBruce Richardson } 25799a2dd95SBruce Richardson 25899a2dd95SBruce Richardson /* 25999a2dd95SBruce Richardson * from RFC 4303 3.3.2.1.4: 26099a2dd95SBruce Richardson * If the ESN option is enabled for the SA, the high-order 32 26199a2dd95SBruce Richardson * bits of the sequence number are appended after the Next Header field 26299a2dd95SBruce Richardson * for purposes of this computation, but are not transmitted. 26399a2dd95SBruce Richardson */ 26499a2dd95SBruce Richardson 26599a2dd95SBruce Richardson /* 26699a2dd95SBruce Richardson * Helper function that moves ICV by 4B below, and inserts SQN.hibits. 26799a2dd95SBruce Richardson * icv parameter points to the new start of ICV. 26899a2dd95SBruce Richardson */ 26999a2dd95SBruce Richardson static inline void 27099a2dd95SBruce Richardson insert_sqh(uint32_t sqh, void *picv, uint32_t icv_len) 27199a2dd95SBruce Richardson { 27299a2dd95SBruce Richardson uint32_t *icv; 27399a2dd95SBruce Richardson int32_t i; 27499a2dd95SBruce Richardson 27599a2dd95SBruce Richardson RTE_ASSERT(icv_len % sizeof(uint32_t) == 0); 27699a2dd95SBruce Richardson 27799a2dd95SBruce Richardson icv = picv; 27899a2dd95SBruce Richardson icv_len = icv_len / sizeof(uint32_t); 27999a2dd95SBruce Richardson for (i = icv_len; i-- != 0; icv[i] = icv[i - 1]) 28099a2dd95SBruce Richardson ; 28199a2dd95SBruce Richardson 28299a2dd95SBruce Richardson icv[i] = sqh; 28399a2dd95SBruce Richardson } 28499a2dd95SBruce Richardson 28599a2dd95SBruce Richardson /* 28699a2dd95SBruce Richardson * Helper function that moves ICV by 4B up, and removes SQN.hibits. 28799a2dd95SBruce Richardson * icv parameter points to the new start of ICV. 28899a2dd95SBruce Richardson */ 28999a2dd95SBruce Richardson static inline void 29099a2dd95SBruce Richardson remove_sqh(void *picv, uint32_t icv_len) 29199a2dd95SBruce Richardson { 29299a2dd95SBruce Richardson uint32_t i, *icv; 29399a2dd95SBruce Richardson 29499a2dd95SBruce Richardson RTE_ASSERT(icv_len % sizeof(uint32_t) == 0); 29599a2dd95SBruce Richardson 29699a2dd95SBruce Richardson icv = picv; 29799a2dd95SBruce Richardson icv_len = icv_len / sizeof(uint32_t); 29899a2dd95SBruce Richardson for (i = 0; i != icv_len; i++) 29999a2dd95SBruce Richardson icv[i] = icv[i + 1]; 30099a2dd95SBruce Richardson } 30199a2dd95SBruce Richardson 30299a2dd95SBruce Richardson /* 30399a2dd95SBruce Richardson * setup crypto ops for LOOKASIDE_NONE (pure crypto) type of devices. 30499a2dd95SBruce Richardson */ 30599a2dd95SBruce Richardson static inline void 30699a2dd95SBruce Richardson lksd_none_cop_prepare(struct rte_crypto_op *cop, 30799a2dd95SBruce Richardson struct rte_cryptodev_sym_session *cs, struct rte_mbuf *mb) 30899a2dd95SBruce Richardson { 30999a2dd95SBruce Richardson struct rte_crypto_sym_op *sop; 31099a2dd95SBruce Richardson 31199a2dd95SBruce Richardson sop = cop->sym; 31299a2dd95SBruce Richardson cop->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 31399a2dd95SBruce Richardson cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 31499a2dd95SBruce Richardson cop->sess_type = RTE_CRYPTO_OP_WITH_SESSION; 31599a2dd95SBruce Richardson sop->m_src = mb; 31699a2dd95SBruce Richardson __rte_crypto_sym_op_attach_sym_session(sop, cs); 31799a2dd95SBruce Richardson } 31899a2dd95SBruce Richardson 31999a2dd95SBruce Richardson #endif /* _CRYPTO_H_ */ 320