1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 /* $FreeBSD$ */ 4 5 /** 6 ***************************************************************************** 7 * @file lac_sym_cipher.h 8 * 9 * @defgroup LacCipher Cipher 10 * 11 * @ingroup LacSym 12 * 13 * API functions of the cipher component 14 * 15 * @lld_start 16 * @lld_overview 17 * There is a single \ref icp_LacSym "Symmetric LAC API" for hash, cipher, 18 * auth encryption and algorithm chaining. This API is implemented by the 19 * \ref LacSym "Symmetric" module. It demultiplexes calls to this API into 20 * their basic operation and does some common parameter checking and deals 21 * with accesses to the session table. 22 * 23 * The cipher component supports data encryption/decryption using the AES, DES, 24 * and Triple-DES cipher algorithms, in ECB, CBC and CTR modes. The ARC4 stream 25 * cipher algorithm is also supported. Data may be provided as a full packet, 26 * or as a sequence of partial packets. The result of the operation can be 27 * written back to the source buffer (in-place) or to a seperate output buffer 28 * (out-of-place). Data must be encapsulated in ICP buffers. 29 * 30 * The cipher component is responsible for implementing the cipher-specific 31 * functionality for registering and de-registering a session, for the perform 32 * operation and for processing the QAT responses to cipher requests. Statistics 33 * are maintained for cipher in the symmetric \ref CpaCySymStats64 "stats" 34 * structure. This module has been seperated out into two. The cipher QAT module 35 * deals entirely with QAT data structures. The cipher module itself has minimal 36 * exposure to the QAT data structures. 37 * 38 * @lld_dependencies 39 * - \ref LacCommon 40 * - \ref LacSymQat "Symmetric QAT": Hash uses the lookup table provided by 41 * this module to validate user input. Hash also uses this module to build 42 * the hash QAT request message, request param structure, populate the 43 * content descriptor, allocate and populate the hash state prefix buffer. 44 * Hash also registers its function to process the QAT response with this 45 * module. 46 * - OSAL : For memory functions, atomics and locking 47 * 48 * @lld_module_algorithms 49 * In general, all the cipher algorithms supported by this component are 50 * implemented entirely by the QAT. However, in the case of the ARC4 algorithm, 51 * it was deemed more efficient to carry out some processing on IA. During 52 * session registration, an initial state is derived from the base key provided 53 * by the user, using a simple ARC4 Key Scheduling Algorithm (KSA). Then the 54 * base key is discarded, but the state is maintained for the duration of the 55 * session. 56 * 57 * The ARC4 key scheduling algorithm (KSA) is specified as follows 58 * (taken from http://en.wikipedia.org/wiki/RC4_(cipher)): 59 * \code 60 * for i from 0 to 255 61 * S[i] := i 62 * endfor 63 * j := 0 64 * for i from 0 to 255 65 * j := (j + S[i] + key[i mod keylength]) mod 256 66 * swap(S[i],S[j]) 67 * endfor 68 * \endcode 69 * 70 * On registration of a new ARC4 session, the user provides a base key of any 71 * length from 1 to 256 bytes. This algorithm produces the initial ARC4 state 72 * (key matrix + i & j index values) from that base key. This ARC4 state is 73 * used as input for each ARC4 cipher operation in that session, and is updated 74 * by the QAT after each operation. The ARC4 state is stored in a session 75 * descriptor, and it's memory is freed when the session is deregistered. 76 * 77 * <b>Block Vs. Stream Ciphers</b>\n 78 * Block ciphers are treated slightly differently than Stream ciphers by this 79 * cipher component. Supported stream ciphers consist of AES and 80 * TripleDES algorithms in CTR mode, and ARC4. The 2 primary differences are: 81 * - Data buffers for block ciphers are required to be a multiple of the 82 * block size defined for the algorithm (e.g. 8 bytes for DES). For stream 83 * ciphers, there is no such restriction. 84 * - For stream ciphers, decryption is performed by setting the QAT hardware 85 * to encryption mode. 86 * 87 * <b>Memory address alignment of data buffers </b>\n 88 * The QAT requires that most data buffers are aligned on an 8-byte memory 89 * address boundary (64-byte boundary for optimum performance). For Cipher, 90 * this applies to the cipher key buffer passed in the Content Descriptor, 91 * and the IV/State buffer passed in the Request Parameters block in each 92 * request. Both of these buffers are provided by the user. It does not 93 * apply to the cipher source/destination data buffers. 94 * Alignment of the key buffer is ensured because the key is always copied 95 * from the user provided buffer into a new (aligned) buffer for the QAT 96 * (the hardware setup block, which configures the QAT slice). This is done 97 * once only during session registration, and the user's key buffer can be 98 * effectively discarded after that. 99 * The IV/State buffer is provided per-request by the user, so it is recommended 100 * to the user to provide aligned buffers for optimal performance. In the case 101 * where an unaligned buffer is provided, a new temporary buffer is allocated 102 * and the user's IV/State data is copied into this buffer. The aligned buffer 103 * is then passed to the QAT in the request. In the response callback, if the 104 * IV was updated by the QAT, the contents are copied back to the user's buffer 105 * and the temporary buffer is freed. 106 * 107 * @lld_process_context 108 * 109 * Session Register Sequence Diagram: For ARC4 cipher algorithm 110 * \msc 111 * APP [label="Application"], SYM [label="Symmetric LAC"], 112 * Achain [label="Alg chain"], Cipher, SQAT [label="Symmetric QAT"]; 113 * 114 * APP=>SYM [ label = "cpaCySymInitSession(cbFunc)", 115 * URL="\ref cpaCySymInitSession()"] ; 116 * SYM=>SYM [ label = "LacSymSession_ParamCheck()", 117 * URL="\ref LacSymSession_ParamCheck()"]; 118 * SYM=>Achain [ label = "LacAlgChain_SessionInit()", 119 * URL="\ref LacAlgChain_SessionInit()"]; 120 * Achain=>Cipher [ label = "LacCipher_SessionSetupDataCheck()", 121 * URL="\ref LacCipher_SessionSetupDataCheck()"]; 122 * Achain<<Cipher [ label="return"]; 123 * Achain=>SQAT [ label = "LacSymQat_CipherContentDescPopulate()", 124 * URL="\ref LacSymQat_CipherContentDescPopulate()"]; 125 * Achain<<SQAT [ label="return"]; 126 * Achain=>SQAT [ label = "LacSymQat_CipherArc4StateInit()", 127 * URL="\ref LacSymQat_CipherArc4StateInit()"]; 128 * Achain<<SQAT [ label="return"]; 129 * SYM<<Achain [ label = "status" ]; 130 * SYM=>SYM [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"]; 131 * APP<<SYM [label = "status"]; 132 * \endmsc 133 * 134 * Perform Sequence Diagram: TripleDES CBC-mode encryption, in-place full 135 *packet, asynchronous mode \msc APP [label="Application"], SYM 136 *[label="Symmetric LAC"], SC [label="Symmetric Common"], Achain [label="Alg 137 *chain"], Cipher, SQAT [label="Symmetric QAT"], BUF [label="LAC Buffer Desc"], 138 *SYMQ [label="Symmetric Queue"], SYMCB [label="Symmetric Callback"], LMP 139 *[label="LAC Mem Pool"], QATCOMMS [label="QAT Comms"]; 140 * 141 * APP=>SYM [ label = "cpaCySymPerformOp()", 142 * URL="\ref cpaCySymPerformOp()"] ; 143 * SYM=>SYM [ label = "LacSym_Perform()", 144 * URL="\ref LacSym_Perform()"]; 145 * SYM=>SYM [ label = "LacSymPerform_BufferParamCheck()", 146 * URL="\ref LacSymPerform_BufferParamCheck()"]; 147 * SYM<<SYM [ label = "status"]; 148 * SYM=>Achain [ label = "LacAlgChain_Perform()", 149 * URL="\ref LacCipher()"]; 150 * Achain=>Cipher [ label = "LacCipher_PerformParamCheck()", 151 * URL="\ref LacCipher_PerformParamCheck()"]; 152 * Achain<<Cipher [ label="status"]; 153 * Achain=>LMP [label="Lac_MemPoolEntryAlloc()", 154 * URL="\ref Lac_MemPoolEntryAlloc()"]; 155 * Achain<<LMP [label="return"]; 156 * Achain=>Cipher [ label = "LacCipher_PerformIvCheckAndAlign()", 157 * URL="\ref LacCipher_PerformIvCheckAndAlign()"]; 158 * Achain<<Cipher [ label="status"]; 159 * Achain=>SQAT [ label = "LacSymQat_CipherRequestParamsPopulate()", 160 * URL="\ref LacSymQat_CipherRequestParamsPopulate()"]; 161 * Achain<<SQAT [ label="return"]; 162 * Achain=>BUF [ label = "LacBuffDesc_BufferListDescWrite()", 163 * URL = "\ref LacBuffDesc_BufferListDescWrite()"]; 164 * Achain<<BUF [ label="return"]; 165 * Achain=>SQAT [ label = "SalQatMsg_CmnMsgAndReqParamsPopulate()", 166 * URL="\ref SalQatMsg_CmnMsgAndReqParamsPopulate()"]; 167 * Achain<<SQAT [ label="return"]; 168 * Achain=>SYMQ [ label = "LacSymQueue_RequestSend()", 169 * URL="\ref LacSymQueue_RequestSend()"]; 170 * SYMQ=>QATCOMMS [ label = "QatComms_MsgSend()", 171 * URL="\ref QatComms_MsgSend()"]; 172 * SYMQ<<QATCOMMS [ label="status"]; 173 * Achain<<SYMQ [ label="status"]; 174 * SYM<<Achain[ label="status"]; 175 * SYM=>SYM [ label = "LacSym_PartialPacketStateUpdate()", 176 * URL="\ref LacSym_PartialPacketStateUpdate()"]; 177 * SYM<<SYM [ label = "return"]; 178 * SYM=>SC [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"]; 179 * SYM<<SC [ label="return"]; 180 * SYM<<SYM [ label = "status"]; 181 * APP<<SYM [label = "status"]; 182 * ... [label = "QAT processing the request and generates response"]; 183 * ...; 184 * QATCOMMS=>QATCOMMS [label ="QatComms_ResponseMsgHandler()", 185 * URL="\ref QatComms_ResponseMsgHandler()"]; 186 * QATCOMMS=>SQAT [label ="LacSymQat_SymRespHandler()", 187 * URL="\ref LacSymQat_SymRespHandler()"]; 188 * SQAT=>SYMCB [label="LacSymCb_ProcessCallback()", 189 * URL="\ref LacSymCb_ProcessCallback()"]; 190 * SYMCB=>SYMCB [label="LacSymCb_ProcessCallbackInternal()", 191 * URL="\ref LacSymCb_ProcessCallbackInternal()"]; 192 * SYMCB=>LMP [label="Lac_MemPoolEntryFree()", 193 * URL="\ref Lac_MemPoolEntryFree()"]; 194 * SYMCB<<LMP [label="return"]; 195 * SYMCB=>SC [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"]; 196 * SYMCB<<SC [label = "return"]; 197 * SYMCB=>APP [label="cbFunc"]; 198 * SYMCB<<APP [label="return"]; 199 * SQAT<<SYMCB [label="return"]; 200 * QATCOMMS<<SQAT [label="return"]; 201 * \endmsc 202 * 203 * #See the sequence diagram for cpaCySymInitSession() 204 * 205 * @lld_end 206 * 207 *****************************************************************************/ 208 209 /***************************************************************************/ 210 211 #ifndef LAC_SYM_CIPHER_H 212 #define LAC_SYM_CIPHER_H 213 214 /* 215 ****************************************************************************** 216 * Include public/global header files 217 ****************************************************************************** 218 */ 219 220 #include "cpa.h" 221 #include "cpa_cy_sym.h" 222 223 /* 224 ******************************************************************************* 225 * Include private header files 226 ******************************************************************************* 227 */ 228 229 #include "lac_session.h" 230 #include "lac_sym.h" 231 #include "lac_sal_types_crypto.h" 232 233 /* 234 * WARNING: There are no checks done on the parameters of the functions in 235 * this file. The expected values of the parameters are documented and it is 236 * up to the caller to provide valid values. 237 */ 238 239 /***************************************************************************/ 240 241 /** 242 ***************************************************************************** 243 * @ingroup LacCipher 244 * Cipher session setup data check 245 * 246 * @description 247 * This function will check any algorithm-specific fields 248 * in the session cipher setup data structure 249 * 250 * @param[in] pCipherSetupData Pointer to session cipher context 251 * 252 * @retval CPA_STATUS_SUCCESS Function executed successfully. 253 * @retval CPA_STATUS_FAIL Function failed. 254 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter. 255 * 256 *****************************************************************************/ 257 CpaStatus 258 LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData *pCipherSetupData, 259 Cpa32U capabilitiesMask); 260 261 /** 262 ******************************************************************************* 263 * @ingroup LacCipher 264 * Function that checks the perform common parameters for cipher 265 * 266 * @description 267 * This function checks the perform parameters for cipher operations 268 * 269 * @param[in] cipherAlgorithm read only pointer to cipher context structure 270 * 271 * @param[in] pOpData read only pointer to user-supplied data for this 272 * cipher operation 273 * @param[in] packetLen read only length of data in buffer 274 * 275 * @retval CPA_STATUS_SUCCESS Success 276 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter 277 * 278 *****************************************************************************/ 279 CpaStatus LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm cipherAlgorithm, 280 const CpaCySymOpData *pOpData, 281 const Cpa64U packetLen); 282 283 /** 284 ***************************************************************************** 285 * @ingroup LacCipher 286 * Cipher perform IV check 287 * 288 * @description 289 * This function will perform algorithm-specific checks on the 290 * cipher Initialisation Vector data provided by the user. 291 * 292 * @param[in] pCbCookie Pointer to struct containing internal cookie 293 * data for the operation 294 * @param[in] qatPacketType QAT partial packet type (start/mid/end/none) 295 * @param[out] ppIvBuffer Returns a pointer to an IV buffer. 296 * 297 * 298 * @retval CPA_STATUS_SUCCESS Function executed successfully. 299 * @retval CPA_STATUS_FAIL Function failed. 300 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter. 301 * 302 * @see LacCipher_Perform(), LacCipher_IvBufferRestore() 303 * 304 * @note LacCipher_IvBufferRestore() must be called when the request is 305 * completed to update the users IV buffer, only in the case of partial 306 * packet requests 307 * 308 *****************************************************************************/ 309 CpaStatus LacCipher_PerformIvCheck(sal_service_t *pService, 310 lac_sym_bulk_cookie_t *pCbCookie, 311 Cpa32U qatPacketType, 312 Cpa8U **ppIvBuffer); 313 314 /** 315 ***************************************************************************** 316 * @ingroup LacCipher 317 * Return cipher slice type for given algorithm 318 * 319 * @description 320 * This function will check what cipher slice type should be used for given 321 * algorithms and CPM generation combination. 322 * Since CPM2.0 there is new UCS cipher slice available. 323 * 324 * @param[in] pService Pointer to service struct 325 * @param[in] cipherAlgorithm cipher algorithm 326 * @param[in] hashAlgorithm hash algorithm 327 * 328 *****************************************************************************/ 329 Cpa32U LacCipher_GetCipherSliceType(sal_crypto_service_t *pService, 330 CpaCySymCipherAlgorithm algorithm, 331 CpaCySymHashAlgorithm hash); 332 #endif /* LAC_SYM_CIPHER_H */ 333