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