blob: e6a7f9949c5fd5e13d7af060dfb0ce720a2ecd7b [file] [log] [blame]
developer02e65912023-08-17 16:33:10 +08001/* sa_builder_macsec.c
2 *
3 * MACsec specific functions (for initialization of SABuilder_Params_t
4 * structures and for building the MACsec specifc part of an SA.).
5 */
6
7/*****************************************************************************
8* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
9*
10* This program is free software: you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation, either version 2 of the License, or
13* any later version.
14*
15* This program is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18* GNU General Public License for more details.
19*
20* You should have received a copy of the GNU General Public License
21* along with this program. If not, see <http://www.gnu.org/licenses/>.
22*****************************************************************************/
23
24/*----------------------------------------------------------------------------
25 * This module implements (provides) the following interface(s):
26 */
27#include "sa_builder_macsec.h"
28#include "sa_builder_internal.h" /* SABuilder_SetMACsecParams */
29
30/*----------------------------------------------------------------------------
31 * This module uses (requires) the following interface(s):
32 */
33#include "c_sa_builder.h"
34#include "basic_defs.h"
35#include "log.h"
36
37#ifdef SAB_ENABLE_PROTO_MACSEC
38
39/*----------------------------------------------------------------------------
40 * Definitions and macros
41 */
42
43
44/*----------------------------------------------------------------------------
45 * Local variables
46 */
47
48/*----------------------------------------------------------------------------
49 * SABuilder_Init_MACsec
50 *
51 * This function initializes the SABuilder_Params_t data structure and its
52 * SABuilder_Params_MACsec_t extension with sensible defaults for MACsec
53 * processing.
54 *
55 * SAParams_p (output)
56 * Pointer to SA parameter structure to be filled in.
57 * SAParamsMACsec_p (output)
58 * Pointer to MACsec parameter extension to be filled in
59 * SCI_p (input)
60 * Pointer to Secure Channel Identifier, 8 bytes.
61 * AN (input)
62 * Association number, a number for 0 to 3.
63 * direction (input)
64 * Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
65 *
66 * Both the crypto and the authentication algorithm are initialized to
67 * NULL. The crypto algorithm (which may remain NULL) must be set to
68 * one of the algorithms supported by the protocol. The authentication
69 * algorithm must also be set to one of the algorithms supported by
70 * the protocol..Any required keys have to be specified as well.
71 *
72 * Both the SAParams_p and SAParamsMACsec_p input parameters must point
73 * to valid storage where variables of the appropriate type can be
74 * stored. This function initializes the link from SAParams_p to
75 * SAParamsMACsec_p.
76 *
77 * Return:
78 * SAB_STATUS_OK on success
79 * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
80 * or the remaining parameters have illegal values.
81 */
82SABuilder_Status_t
83SABuilder_Init_MACsec(
84 SABuilder_Params_t * const SAParams_p,
85 SABuilder_Params_MACsec_t * const SAParamsMACsec_p,
86 const uint8_t *SCI_p,
87 const uint8_t AN,
88 const SABuilder_Direction_t direction)
89{
90#ifdef SAB_STRICT_ARGS_CHECK
91 if (SAParams_p == NULL || SAParamsMACsec_p == NULL || SCI_p == NULL)
92 {
93 LOG_CRIT("SABuilder_Init_MACsec: NULL pointer parameter supplied.\n");
94 return SAB_INVALID_PARAMETER;
95 }
96
97 if (AN > 3)
98 {
99 LOG_CRIT("SABuilder_Init_MACsec: Invalid Association Number.\n");
100 return SAB_INVALID_PARAMETER;
101 }
102
103 if (direction != SAB_DIRECTION_OUTBOUND &&
104 direction != SAB_DIRECTION_INBOUND)
105 {
106 LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
107 return SAB_INVALID_PARAMETER;
108 }
109#endif
110
111 SAParams_p->protocol = SAB_PROTO_MACSEC;
112 SAParams_p->direction = direction;
113 SAParams_p->ProtocolExtension_p = (void*)SAParamsMACsec_p;
114 SAParams_p->flags = 0;
115 SAParams_p->RedirectInterface = 0;
116
117 SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
118 SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
119 SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
120 SAParams_p->CryptoParameter = 0;
121 SAParams_p->KeyByteCount = 0;
122 SAParams_p->Key_p = NULL;
123 SAParams_p->IV_p = NULL;
124 SAParams_p->Nonce_p = NULL;
125
126 SAParams_p->AuthAlgo = SAB_AUTH_NULL;
127 SAParams_p->AuthKey1_p = NULL;
128 SAParams_p->AuthKey2_p = NULL;
129 SAParams_p->AuthKey3_p = NULL;
130 SAParams_p->AuthKeyByteCount = 0;
131
132 SAParams_p->OffsetARC4StateRecord = 0;
133 SAParams_p->CW0 = 0;
134 SAParams_p->CW1 = 0;
135 SAParams_p->OffsetDigest0 = 0;
136 SAParams_p->OffsetDigest1 = 0;
137 SAParams_p->OffsetSeqNum = 0;
138 SAParams_p->OffsetSeqMask = 0;
139 SAParams_p->OffsetIV = 0;
140 SAParams_p->OffsetIJPtr = 0;
141 SAParams_p->OffsetARC4State = 0;
142 SAParams_p->SeqNumWord32Count = 0;
143 SAParams_p->SeqMaskWord32Count = 0;
144 SAParams_p->IVWord32Count = 0;
145
146 SAParamsMACsec_p->MACsecFlags = 0;
147 SAParamsMACsec_p->SCI_p = SCI_p;
148 SAParamsMACsec_p->AN = AN;
149 SAParamsMACsec_p->SeqNum = 0;
150 SAParamsMACsec_p->ReplayWindow = 0;
151 SAParamsMACsec_p->ConfOffset = 0;
152 SAParamsMACsec_p->ContextRef = 0;
153
154 return SAB_STATUS_OK;
155}
156
157/*----------------------------------------------------------------------------
158 * SABuilder_SetMACsecParams
159 *
160 * Fill in MACsec-specific extensions into the SA.
161 *
162 * SAParams_p (input)
163 * The SA parameters structure from which the SA is derived.
164 * SAState_p (input, output)
165 * Variables containing information about the SA being generated/
166 * SABuffer_p (input, output).
167 * The buffer in which the SA is built. If NULL, no SA will be built, but
168 * state variables in SAState_p will still be updated.
169 *
170 * Return:
171 * SAB_STATUS_OK on success
172 * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
173 * the buffer arguments is a null pointer while the corresponding buffer
174 * would be required for the operation.
175 * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
176 * is not supported on the hardware for which this SA builder
177 * is configured.
178 */
179SABuilder_Status_t
180SABuilder_SetMACsecParams(SABuilder_Params_t *const SAParams_p,
181 SABuilder_State_t * const SAState_p,
182 uint32_t * const SABuffer_p)
183{
184 SABuilder_Params_MACsec_t *SAParamsMACsec_p;
185 SAParamsMACsec_p = (SABuilder_Params_MACsec_t *)
186 (SAParams_p->ProtocolExtension_p);
187 if (SAParamsMACsec_p == NULL)
188 {
189 LOG_CRIT("SABuilder: MACsec extension pointer is null\n");
190 return SAB_INVALID_PARAMETER;
191 }
192
193 /* Allow only AES-GMAC and AES-GCM */
194 if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
195 SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC)
196 {
197 LOG_CRIT("SABuilder: Only AES-GCM and GMAC allowed wtih MACsec\n");
198 return SAB_INVALID_PARAMETER;
199 }
200
201 if ( (SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_ES) != 0 &&
202 (SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SC) != 0)
203 {
204 LOG_CRIT("SABuilder: MACSEC if ES is set, then SC must be zero,\n");
205 return SAB_INVALID_PARAMETER;
206 }
207
208 /* Add sequence number */
209 SAState_p->CW0 |= SAB_CW0_SEQNUM_32;
210 SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
211 SAParams_p->SeqNumWord32Count = 1;
212 SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
213
214 if (SABuffer_p != NULL)
215 SABuffer_p[SAState_p->CurrentOffset] = SAParamsMACsec_p->SeqNum;
216 SAState_p->CurrentOffset += 1;
217
218 if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
219 {
220 if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
221 SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
222 else
223 SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
224 /* Some versions of the hardware can update the sequence number
225 early, so multiple engines can operate in parallel. */
226 SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
227 SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
228 }
229 else
230 {
231 SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
232
233 /* Add 'sequence number mask' parameter, which is the replay
234 window size */
235 SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
236 if(SABuffer_p != NULL)
237 {
238 SABuffer_p[SAState_p->CurrentOffset] =
239 SAParamsMACsec_p->ReplayWindow;
240 SABuffer_p[SAState_p->CurrentOffset+1] = 0; // Add dummy mask word.
241 }
242 SAParams_p->SeqMaskWord32Count = 1;
243 SAState_p->CurrentOffset += 2;
244 SAState_p->CW0 |= SAB_CW0_MASK_32;
245 SAState_p->CW1 |= SAB_CW1_MACSEC_SEQCHECK|SAB_CW1_NO_MASK_UPDATE;
246 }
247
248 /* Add SCI (IV0 and IV1) */
249 SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV0 | SAB_CW1_IV1 | SAB_CW1_IV2;
250#ifdef SAB_STRICT_ARGS_CHECK
251 if (SAParamsMACsec_p->SCI_p == NULL)
252 {
253 LOG_CRIT("SABuilder: NULL pointer SCI.\n");
254 return SAB_INVALID_PARAMETER;
255 }
256#endif
257 SAParams_p->OffsetIV = SAState_p->CurrentOffset;
258 SAParams_p->IVWord32Count = 2;
259
260 SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
261 SAParamsMACsec_p->SCI_p, 8);
262 SAState_p->CurrentOffset += 2;
263
264 /* Add sequence number once more (IV2) */
265 if (SABuffer_p != NULL)
266 SABuffer_p[SAState_p->CurrentOffset] = SAParamsMACsec_p->SeqNum;
267 SAState_p->CurrentOffset += 1;
268
269 return SAB_STATUS_OK;
270}
271
272
273#endif /* SAB_ENABLE_PROTO_MACSEC */
274
275/* end of file sa_builder_macsec.c */