1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 #ifndef _CRYPTO_H_ 6 #define _CRYPTO_H_ 7 8 /** 9 * @file crypto.h 10 * Contains crypto specific functions/structures/macros used internally 11 * by ipsec library. 12 */ 13 14 /* 15 * AES-CTR counter block format. 16 */ 17 18 struct aesctr_cnt_blk { 19 uint32_t nonce; 20 uint64_t iv; 21 uint32_t cnt; 22 } __rte_packed; 23 24 /* 25 * AES-GCM devices have some specific requirements for IV and AAD formats. 26 * Ideally that to be done by the driver itself. 27 */ 28 29 struct aead_gcm_iv { 30 uint32_t salt; 31 uint64_t iv; 32 uint32_t cnt; 33 } __rte_packed; 34 35 struct aead_gcm_aad { 36 uint32_t spi; 37 /* 38 * RFC 4106, section 5: 39 * Two formats of the AAD are defined: 40 * one for 32-bit sequence numbers, and one for 64-bit ESN. 41 */ 42 union { 43 uint32_t u32[2]; 44 uint64_t u64; 45 } sqn; 46 uint32_t align0; /* align to 16B boundary */ 47 } __rte_packed; 48 49 struct gcm_esph_iv { 50 struct rte_esp_hdr esph; 51 uint64_t iv; 52 } __rte_packed; 53 54 static inline void 55 aes_ctr_cnt_blk_fill(struct aesctr_cnt_blk *ctr, uint64_t iv, uint32_t nonce) 56 { 57 ctr->nonce = nonce; 58 ctr->iv = iv; 59 ctr->cnt = rte_cpu_to_be_32(1); 60 } 61 62 static inline void 63 aead_gcm_iv_fill(struct aead_gcm_iv *gcm, uint64_t iv, uint32_t salt) 64 { 65 gcm->salt = salt; 66 gcm->iv = iv; 67 gcm->cnt = rte_cpu_to_be_32(1); 68 } 69 70 /* 71 * RFC 4106, 5 AAD Construction 72 * spi and sqn should already be converted into network byte order. 73 * Make sure that not used bytes are zeroed. 74 */ 75 static inline void 76 aead_gcm_aad_fill(struct aead_gcm_aad *aad, rte_be32_t spi, rte_be64_t sqn, 77 int esn) 78 { 79 aad->spi = spi; 80 if (esn) 81 aad->sqn.u64 = sqn; 82 else { 83 aad->sqn.u32[0] = sqn_low32(sqn); 84 aad->sqn.u32[1] = 0; 85 } 86 aad->align0 = 0; 87 } 88 89 static inline void 90 gen_iv(uint64_t iv[IPSEC_MAX_IV_QWORD], rte_be64_t sqn) 91 { 92 iv[0] = sqn; 93 iv[1] = 0; 94 } 95 96 /* 97 * Helper routine to copy IV 98 * Right now we support only algorithms with IV length equals 0/8/16 bytes. 99 */ 100 static inline void 101 copy_iv(uint64_t dst[IPSEC_MAX_IV_QWORD], 102 const uint64_t src[IPSEC_MAX_IV_QWORD], uint32_t len) 103 { 104 RTE_BUILD_BUG_ON(IPSEC_MAX_IV_SIZE != 2 * sizeof(uint64_t)); 105 106 switch (len) { 107 case IPSEC_MAX_IV_SIZE: 108 dst[1] = src[1]; 109 /* fallthrough */ 110 case sizeof(uint64_t): 111 dst[0] = src[0]; 112 /* fallthrough */ 113 case 0: 114 break; 115 default: 116 /* should never happen */ 117 RTE_ASSERT(NULL); 118 } 119 } 120 121 /* 122 * from RFC 4303 3.3.2.1.4: 123 * If the ESN option is enabled for the SA, the high-order 32 124 * bits of the sequence number are appended after the Next Header field 125 * for purposes of this computation, but are not transmitted. 126 */ 127 128 /* 129 * Helper function that moves ICV by 4B below, and inserts SQN.hibits. 130 * icv parameter points to the new start of ICV. 131 */ 132 static inline void 133 insert_sqh(uint32_t sqh, void *picv, uint32_t icv_len) 134 { 135 uint32_t *icv; 136 int32_t i; 137 138 RTE_ASSERT(icv_len % sizeof(uint32_t) == 0); 139 140 icv = picv; 141 icv_len = icv_len / sizeof(uint32_t); 142 for (i = icv_len; i-- != 0; icv[i] = icv[i - 1]) 143 ; 144 145 icv[i] = sqh; 146 } 147 148 /* 149 * Helper function that moves ICV by 4B up, and removes SQN.hibits. 150 * icv parameter points to the new start of ICV. 151 */ 152 static inline void 153 remove_sqh(void *picv, uint32_t icv_len) 154 { 155 uint32_t i, *icv; 156 157 RTE_ASSERT(icv_len % sizeof(uint32_t) == 0); 158 159 icv = picv; 160 icv_len = icv_len / sizeof(uint32_t); 161 for (i = 0; i != icv_len; i++) 162 icv[i] = icv[i + 1]; 163 } 164 165 /* 166 * setup crypto ops for LOOKASIDE_NONE (pure crypto) type of devices. 167 */ 168 static inline void 169 lksd_none_cop_prepare(struct rte_crypto_op *cop, 170 struct rte_cryptodev_sym_session *cs, struct rte_mbuf *mb) 171 { 172 struct rte_crypto_sym_op *sop; 173 174 sop = cop->sym; 175 cop->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 176 cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; 177 cop->sess_type = RTE_CRYPTO_OP_WITH_SESSION; 178 sop->m_src = mb; 179 __rte_crypto_sym_op_attach_sym_session(sop, cs); 180 } 181 182 #endif /* _CRYPTO_H_ */ 183