1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4
5 /**
6 ***************************************************************************
7 * @file lac_sym_auth_enc.c
8 *
9 * @ingroup LacAuthEnc
10 *
11 * @description
12 * Authenticated encryption specific functionality.
13 * For CCM related code NIST SP 800-38C is followed.
14 * For GCM related code NIST SP 800-38D is followed.
15 ***************************************************************************/
16
17 /*
18 *******************************************************************************
19 * Include public/global header files
20 *******************************************************************************
21 */
22
23 #include "cpa.h"
24 #include "cpa_cy_sym.h"
25
26 #include "icp_accel_devices.h"
27 #include "icp_adf_init.h"
28 #include "icp_adf_transport.h"
29 #include "icp_adf_debug.h"
30 /*
31 *******************************************************************************
32 * Include private header files
33 *******************************************************************************
34 */
35 #include "lac_log.h"
36 #include "lac_common.h"
37 #include "lac_session.h"
38 #include "lac_sym_auth_enc.h"
39
40 /* These defines describe position of the flag fields
41 * in B0 block for CCM algorithm*/
42 #define LAC_ALG_CHAIN_CCM_B0_FLAGS_ADATA_SHIFT 6
43 #define LAC_ALG_CHAIN_CCM_B0_FLAGS_T_SHIFT 3
44
45 /* This macro builds flags field to be put in B0 block for CCM algorithm */
46 #define LAC_ALG_CHAIN_CCM_BUILD_B0_FLAGS(Adata, t, q) \
47 ((((Adata) > 0 ? 1 : 0) << LAC_ALG_CHAIN_CCM_B0_FLAGS_ADATA_SHIFT) | \
48 ((((t)-2) >> 1) << LAC_ALG_CHAIN_CCM_B0_FLAGS_T_SHIFT) | ((q)-1))
49
50 /**
51 * @ingroup LacAuthEnc
52 */
53 CpaStatus
54 LacSymAlgChain_CheckCCMData(Cpa8U *pAdditionalAuthData,
55 Cpa8U *pIv,
56 Cpa32U messageLenToCipherInBytes,
57 Cpa32U ivLenInBytes)
58 {
59 Cpa8U q = 0;
60
61 LAC_CHECK_NULL_PARAM(pIv);
62 LAC_CHECK_NULL_PARAM(pAdditionalAuthData);
63
64 /* check if n is within permitted range */
65 if (ivLenInBytes < LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MIN ||
66 ivLenInBytes > LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MAX) {
67 LAC_INVALID_PARAM_LOG2("ivLenInBytes for CCM algorithm "
68 "must be between %d and %d inclusive",
69 LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MIN,
70 LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MAX);
71 return CPA_STATUS_INVALID_PARAM;
72 }
73
74 q = LAC_ALG_CHAIN_CCM_NQ_CONST - ivLenInBytes;
75
76 /* Check if q is big enough to hold actual length of message to cipher
77 * if q = 8 -> maxlen = 2^64 always good as
78 * messageLenToCipherInBytes is 32 bits
79 * if q = 7 -> maxlen = 2^56 always good
80 * if q = 6 -> maxlen = 2^48 always good
81 * if q = 5 -> maxlen = 2^40 always good
82 * if q = 4 -> maxlen = 2^32 always good.
83 */
84 if ((messageLenToCipherInBytes >= (1 << (q * LAC_NUM_BITS_IN_BYTE))) &&
85 (q < sizeof(Cpa32U))) {
86 LAC_INVALID_PARAM_LOG(
87 "messageLenToCipherInBytes too long for the given"
88 " ivLenInBytes for CCM algorithm\n");
89 return CPA_STATUS_INVALID_PARAM;
90 }
91
92 return CPA_STATUS_SUCCESS;
93 }
94
95
96 /**
97 * @ingroup LacAuthEnc
98 */
99 void
100 LacSymAlgChain_PrepareCCMData(lac_session_desc_t *pSessionDesc,
101 Cpa8U *pAdditionalAuthData,
102 Cpa8U *pIv,
103 Cpa32U messageLenToCipherInBytes,
104 Cpa32U ivLenInBytes)
105 {
106 Cpa8U n =
107 ivLenInBytes; /* assumes ivLenInBytes has been param checked */
108 Cpa8U q = LAC_ALG_CHAIN_CCM_NQ_CONST - n;
109 Cpa8U lenOfEncodedLen = 0;
110 Cpa16U lenAEncoded = 0;
111 Cpa32U bitStrQ = 0;
112
113 /* populate Ctr0 block - stored in pIv */
114 pIv[0] = (q - 1);
115 /* bytes 1 to n are already set with nonce by the user */
116 /* set last q bytes with 0 */
117 memset(pIv + n + 1, 0, q);
118
119 /* Encode the length of associated data 'a'. As the API limits the
120 * length
121 * of an array pointed by pAdditionalAuthData to be 240 bytes max, the
122 * maximum length of 'a' might be 240 - 16 - 2 = 222. Hence the encoding
123 * below is simplified. */
124 if (pSessionDesc->aadLenInBytes > 0) {
125 lenOfEncodedLen = sizeof(Cpa16U);
126 lenAEncoded = QAT_UTILS_HOST_TO_NW_16(
127 (Cpa16U)pSessionDesc->aadLenInBytes);
128 }
129
130 /* populate B0 block */
131 /* first, set the flags field */
132 pAdditionalAuthData[0] =
133 LAC_ALG_CHAIN_CCM_BUILD_B0_FLAGS(lenOfEncodedLen,
134 pSessionDesc->hashResultSize,
135 q);
136 /* bytes 1 to n are already set with nonce by the user*/
137 /* put Q in bytes 16-q...15 */
138 bitStrQ = QAT_UTILS_HOST_TO_NW_32(messageLenToCipherInBytes);
139
140 if (q > sizeof(bitStrQ)) {
141 memset(pAdditionalAuthData + n + 1, 0, q);
142 memcpy(pAdditionalAuthData + n + 1 + (q - sizeof(bitStrQ)),
143 (Cpa8U *)&bitStrQ,
144 sizeof(bitStrQ));
145 } else {
146 memcpy(pAdditionalAuthData + n + 1,
147 ((Cpa8U *)&bitStrQ) + (sizeof(bitStrQ) - q),
148 q);
149 }
150
151 /* populate B1-Bn blocks */
152 if (lenAEncoded > 0) {
153 *(Cpa16U
154 *)(&pAdditionalAuthData[1 + LAC_ALG_CHAIN_CCM_NQ_CONST]) =
155 lenAEncoded;
156 /* Next bytes are already set by the user with
157 * the associated data 'a' */
158
159 /* Check if padding is required */
160 if (((pSessionDesc->aadLenInBytes + lenOfEncodedLen) %
161 LAC_HASH_AES_CCM_BLOCK_SIZE) != 0) {
162 Cpa8U paddingLen = 0;
163 Cpa8U paddingIndex = 0;
164
165 paddingLen = LAC_HASH_AES_CCM_BLOCK_SIZE -
166 ((pSessionDesc->aadLenInBytes + lenOfEncodedLen) %
167 LAC_HASH_AES_CCM_BLOCK_SIZE);
168
169 paddingIndex = 1 + LAC_ALG_CHAIN_CCM_NQ_CONST;
170 paddingIndex +=
171 lenOfEncodedLen + pSessionDesc->aadLenInBytes;
172
173 memset(&pAdditionalAuthData[paddingIndex],
174 0,
175 paddingLen);
176 }
177 }
178 }
179
180 /**
181 * @ingroup LacAuthEnc
182 */
183 void
184 LacSymAlgChain_PrepareGCMData(lac_session_desc_t *pSessionDesc,
185 Cpa8U *pAdditionalAuthData)
186 {
187 Cpa8U paddingLen = 0;
188
189 if ((pSessionDesc->aadLenInBytes % LAC_HASH_AES_GCM_BLOCK_SIZE) != 0) {
190 paddingLen = LAC_HASH_AES_GCM_BLOCK_SIZE -
191 (pSessionDesc->aadLenInBytes % LAC_HASH_AES_GCM_BLOCK_SIZE);
192
193 memset(&pAdditionalAuthData[pSessionDesc->aadLenInBytes],
194 0,
195 paddingLen);
196 }
197 }
Cache object: a80e128ce37a408bd6a8db77821d6919
|