1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 4 /** 5 *************************************************************************** 6 * @file lac_sym_partial.h 7 * 8 * @defgroup LacSymPartial Partial Packets 9 * 10 * @ingroup LacSymCommon 11 * 12 * Partial packet handling code 13 * 14 * @lld_start 15 * 16 * <b>Partials In Flight</b>\n 17 * The API states that for partial packets the client should not submit 18 * the next partial request until the callback for the current partial has 19 * been called. We have chosen to enforce this rather than letting the user 20 * proceed where they would get an incorrect digest, cipher result. 21 * 22 * Maintain a SpinLock for partials in flight per session. Try and acquire this 23 * SpinLock. If it cant be acquired return an error straight away to the client 24 * as there is already a partial in flight. There is no blocking in the data 25 * path for this. 26 * 27 * By preventing any other partials from coming in while a partial is in flight 28 * we can check and change the state of the session without having to lock 29 * round it (dont want to have to lock and block in the data path). The state 30 * of the session indicates the previous packet type that a request was 31 * successfully completed for. The last packet type is only updated for partial 32 * packets. This state determines the packet types that can be accepted. 33 * e.g a last partial will not be accepted unless the previous packet was a 34 * partial. By only allowing one partial packet to be in flight, there is no 35 * need to lock around the update of the previous packet type for the session. 36 * 37 * The ECB Cipher mode, ciphers each block separately. No state is maintained 38 * between blocks. There is no need to wait for the callback for previous 39 * partial in ECB mode as the result of the previous partial has no impact on 40 * it. The API and our implementation only allows 1 partial packet to be in 41 * flight per session, therefore a partial packet request for ECB mode must 42 * be fully completed (ie. callback called) before the next partial request 43 * can be issued. 44 * 45 * <b>Partial Ordering</b>\n 46 * The ordering that the user submits partial packets will be checked. 47 * (we could have let the user proceed where they will get an incorrect 48 * digest/cipher result but chose against this). 49 * 50 * -# Maintain the last packet type of a partial operation for the session. If 51 * there have been no previous partials, we will accept only first partials 52 * -# The state must be set to partial before we will accept a final partial. 53 * i.e. a partial request must have already completed. 54 * 55 * The last packet type is updated in the callback for partial packets as this 56 * is the only place we can guarantee that a partial packet operation has been 57 * completed. When a partial completes the state can be updated from FULL to 58 * PARTIAL. The SpinLock for partial packets in flight for the session can be 59 * unlocked at this point. On a final Partial request the last packet type is 60 * reset back to FULL. NOTE: This is not done at the same time as the check in 61 * the perform as if an error occurs we would have to roll back the state 62 * 63 * For Hash mode it is possible to interleave full and a single partial 64 * packet stream in a session as the hash state buffer is updated for partial 65 * packets. It is not touched by full packets. For cipher mode, as the client 66 * manages the state, they can interleave full and a single partial packets. 67 * For ARC4, the state is managed internally and the packet type will always 68 * be set to partial internally. 69 * 70 * @lld_end 71 * 72 ***************************************************************************/ 73 74 /***************************************************************************/ 75 76 #ifndef LAC_SYM_PARTIAL_H 77 #define LAC_SYM_PARTIAL_H 78 79 #include "cpa.h" 80 #include "cpa_cy_sym.h" 81 82 /***************************************************************************/ 83 84 /** 85 ******************************************************************************* 86 * @ingroup LacSymPartial 87 * check if partial packet request is valid for a session 88 * 89 * @description 90 * This function checks to see if there is a partial packet request in 91 * flight and then if the partial state is correct 92 * 93 * @param[in] packetType Partial packet request 94 * @param[in] partialState Partial state of session 95 * 96 * @retval CPA_STATUS_SUCCESS Normal Operation 97 * @retval CPA_STATUS_INVALID_PARAM Invalid Parameter 98 * 99 *****************************************************************************/ 100 CpaStatus LacSym_PartialPacketStateCheck(CpaCySymPacketType packetType, 101 CpaCySymPacketType partialState); 102 103 /** 104 ******************************************************************************* 105 * @ingroup LacSymPartial 106 * update the state of the partial packet in a session 107 * 108 * @description 109 * This function is called in callback operation. It updates the state 110 * of a partial packet in a session and indicates that there is no 111 * longer a partial packet in flight for the session 112 * 113 * @param[in] packetType Partial packet request 114 * @param[out] pPartialState Pointer to partial state of session 115 * 116 *****************************************************************************/ 117 void LacSym_PartialPacketStateUpdate(CpaCySymPacketType packetType, 118 CpaCySymPacketType *pPartialState); 119 120 #endif /* LAC_SYM_PARTIAL_H */ 121