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