blob: 84401f4aac2e2fecd485d2f12fec134234d32c14 [file] [log] [blame]
developer02e65912023-08-17 16:33:10 +08001/* sa_builder.c
2 *
3 * Main implementation file of the EIP-96 SA builder.
4 */
5
6/*****************************************************************************
7* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
8*
9* This program is free software: you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by
11* the Free Software Foundation, either version 2 of the License, or
12* any later version.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License
20* along with this program. If not, see <http://www.gnu.org/licenses/>.
21*****************************************************************************/
22
23/*----------------------------------------------------------------------------
24 * This module implements (provides) the following interface(s):
25 */
26#include "sa_builder.h"
27
28/*----------------------------------------------------------------------------
29 * This module uses (requires) the following interface(s):
30 */
31#include "c_sa_builder.h"
32#include "basic_defs.h"
33#include "log.h"
34#include "sa_builder_internal.h"
35
36#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
37#include "token_builder.h"
38#endif
39
40#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_BASIC_EXTENDED)
41#include "sa_builder_extended_internal.h"
42#include "firmware_eip207_api_flow_cs.h"
43#endif
44
45
46/*----------------------------------------------------------------------------
47 * Local variables
48 */
49#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_SSLTLS_EXTENDED)
50unsigned int LargeTransformOffset = SAB_LARGE_TRANSFORM_OFFSET;
51#else
52#define LargeTransformOffset 16
53#endif
54
55/*----------------------------------------------------------------------------
56 * SABuilderLib_CopyKeyMat
57 *
58 * Copy a key into the SA.
59 *
60 * Destination_p (input)
61 * Destination (word-aligned) of the SA record.
62 *
63 * offset (input)
64 * Word offset of the key in the SA record where it must be stored.
65 *
66 * Source_p (input)
67 * Source (byte aligned) of the data.
68 *
69 * KeyByteCount (input)
70 * Size of the key in bytes.
71 *
72 * Destination_p is allowed to be a null pointer, in which case no key
73 * will be written.
74 */
75void
76SABuilderLib_CopyKeyMat(
77 uint32_t * const Destination_p,
78 const unsigned int offset,
79 const uint8_t * const Source_p,
80 const unsigned int KeyByteCount)
81{
82 uint32_t *dst = Destination_p + offset;
83 const uint8_t *src = Source_p;
84 unsigned int i,j;
85 uint32_t w;
86 if (Destination_p == NULL)
87 return;
88 for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
89 {
90 w=0;
91 for(j=0; j<sizeof(uint32_t); j++)
92 w=(w>>8)|(*src++ << 24);
93 *dst++ = w;
94 }
95 if ((KeyByteCount % sizeof(uint32_t)) != 0)
96 {
97 w=0;
98 for(j=0; j<KeyByteCount % sizeof(uint32_t); j++)
99 {
100 w = w | (*src++ << (j*8));
101 }
102 *dst++ = w;
103 }
104}
105
106
107/*----------------------------------------------------------------------------
108 * SABuilderLib_CopyKeyMatSwap
109 *
110 * Copy a key into the SA with the words byte-swapped.
111 *
112 * Destination_p (input)
113 * Destination (word-aligned) to store the data.
114 *
115 * offset (input)
116 * Word offset of the key in the SA record where it must be stored.
117 *
118 * Source_p (input)
119 * Source (byte aligned) of the data.
120 *
121 * KeyByteCount (input)
122 * Size of the key in bytes.
123 *
124 * Destination_p is allowed to be a null pointer, in which case no key
125 * will be written.
126 */
127void
128SABuilderLib_CopyKeyMatSwap(
129 uint32_t * const Destination_p,
130 const unsigned int offset,
131 const uint8_t * const Source_p,
132 const unsigned int KeyByteCount)
133{
134 uint32_t *dst = Destination_p + offset;
135 const uint8_t *src = Source_p;
136 unsigned int i,j;
137 uint32_t w;
138
139 if (Destination_p == NULL)
140 return;
141
142 for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
143 {
144 w=0;
145
146 for(j=0; j<sizeof(uint32_t); j++)
147 w=(w<<8)|(*src++);
148
149 *dst++ = w;
150 }
151 if ((KeyByteCount % sizeof(uint32_t)) != 0)
152 {
153 w=0;
154 for(j=0; j<KeyByteCount % sizeof(uint32_t); j++)
155 {
156 w = w | (*src++ << (24 - j*8));
157 }
158 *dst++ = w;
159 }
160}
161
162
163/*----------------------------------------------------------------------------
164 * SABuilderLib_ZeroFill
165 *
166 * Fill an area in the SA with zero bytes.
167 *
168 * Destination_p (input)
169 * Destination (word-aligned) of the SA record.
170 *
171 * offset (input)
172 * Word offset of the area in the SA that must be zero-filled.
173 *
174 * ByteCount (input)
175 * Number of bytes to write.
176 *
177 * Destination_p is allowed to be a null pointer, in which case no zeroes
178 * will be written.
179 */
180void
181SABuilderLib_ZeroFill(
182 uint32_t * const Destination_p,
183 const unsigned int offset,
184 const unsigned int ByteCount)
185{
186 uint32_t *dst = Destination_p + offset;
187 unsigned int i;
188 if (Destination_p == NULL)
189 return;
190 for(i=0; i < (ByteCount + sizeof(uint32_t) - 1) / sizeof(uint32_t); i++)
191 {
192 *dst++ = 0;
193 }
194}
195
196#ifdef SAB_ARC4_STATE_IN_SA
197/*----------------------------------------------------------------------------
198 * SABuilder_AlignForARc4State
199 *
200 * Align CurrentOffset to the alignment as specified by
201 * SAB_ARC4_STATE_ALIGN_BYTE_COUNT
202 */
203static unsigned int
204SABuilder_AlignForARc4State(
205 unsigned int CurrentOffset)
206{
207#if SAB_ARC4_STATE_ALIGN_BYTE_COUNT <= 4
208 return CurrentOffset;
209#else
210 uint32_t AlignMask = (SAB_ARC4_STATE_ALIGN_BYTE_COUNT >> 2) - 1;
211 return (CurrentOffset + AlignMask) & ~AlignMask;
212#endif
213}
214#endif
215
216
217/*----------------------------------------------------------------------------
218 * SABuilder_SetCipherKeys
219 *
220 * Fill in cipher keys and associated command word fields in SA.
221 *
222 * SAParams_p (input)
223 * The SA parameters structure from which the SA is derived.
224 *
225 * SAState_p (input, output)
226 * Variables containing information about the SA being generated.
227 *
228 * SABuffer_p (input, output).
229 * The buffer in which the SA is built. If NULL, no SA will be built, but
230 * state variables in SAState_p will still be updated.
231 *
232 * Return:
233 * SAB_STATUS_OK on success
234 * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
235 * the buffer arguments is a null pointer while the corresponding buffer
236 * would be required for the operation.
237 * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
238 * is not supported on the hardware for which this SA builder
239 * is configured.
240 */
241static SABuilder_Status_t
242SABuilder_SetCipherKeys(
243 SABuilder_Params_t *const SAParams_p,
244 SABuilder_State_t * const SAState_p,
245 uint32_t * const SABuffer_p)
246{
247 /* Fill in crypto-algorithm specific parameters */
248 switch (SAParams_p->CryptoAlgo)
249 {
250 case SAB_CRYPTO_NULL: /* Null crypto, do nothing */
251 break;
252#ifdef SAB_ENABLE_CRYPTO_3DES
253 case SAB_CRYPTO_DES:
254 SAState_p->CipherKeyWords = 2;
255 SAState_p->IVWords = 2;
256 SAState_p->CW0 |= SAB_CW0_CRYPTO_DES;
257 break;
258 case SAB_CRYPTO_3DES:
259 SAState_p->CipherKeyWords = 6;
260 SAState_p->IVWords = 2;
261 SAState_p->CW0 |= SAB_CW0_CRYPTO_3DES;
262 break;
263#endif
264#ifdef SAB_ENABLE_CRYPTO_AES
265 case SAB_CRYPTO_AES:
266 switch (SAParams_p->KeyByteCount)
267 {
268 case 16:
269 SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_128;
270 SAState_p->CipherKeyWords = 4;
271 break;
272 case 24:
273 SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_192;
274 SAState_p->CipherKeyWords = 6;
275 break;
276 case 32:
277 SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_256;
278 SAState_p->CipherKeyWords = 8;
279 break;
280 default:
281 LOG_CRIT("SABuilder: Bad key size for AES.\n");
282 return SAB_INVALID_PARAMETER;
283 }
284 SAState_p->IVWords = 4;
285 break;
286#endif
287#ifdef SAB_ENABLE_CRYPTO_ARCFOUR
288 case SAB_CRYPTO_ARCFOUR:
289 SAState_p->CW0 |= SAB_CW0_CRYPTO_ARC4;
290 if (SAParams_p->KeyByteCount < 5 ||
291 SAParams_p->KeyByteCount > 16)
292 {
293 LOG_CRIT("SABuilder: Bad key size for ARCFOUR.\n");
294 return SAB_INVALID_PARAMETER;
295 }
296 SAState_p->CW1 |= SAParams_p->KeyByteCount;
297 SAState_p->CipherKeyWords =
298 ((unsigned int)SAParams_p->KeyByteCount + sizeof(uint32_t) - 1) /
299 sizeof(uint32_t);
300
301 if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATELESS)
302 {
303 SAState_p->ARC4State = true;
304 SAState_p->CW1 |= SAB_CW1_ARC4_IJ_PTR | SAB_CW1_ARC4_STATE_SEL |
305 SAB_CW1_CRYPTO_STORE;
306 }
307 break;
308#endif
309#ifdef SAB_ENABLE_CRYPTO_SM4
310 case SAB_CRYPTO_SM4:
311 SAState_p->CipherKeyWords = 4;
312 SAState_p->IVWords = 4;
313 SAState_p->CW0 |= SAB_CW0_CRYPTO_SM4;
314 break;
315#endif
316#ifdef SAB_ENABLE_CRYPTO_BC0
317 case SAB_CRYPTO_BC0:
318 SAState_p->CipherKeyWords = 8;
319 SAState_p->IVWords = 4;
320 SAState_p->CW0 |= SAB_CW0_CRYPTO_BC0 +
321 ((SAParams_p->CryptoParameter & 0x3) << 17) ;
322 SAState_p->CW1 |= SAB_CW1_EXT_CIPHER_SET;
323 break;
324#endif
325#ifdef SAB_ENABLE_CRYPTO_KASUMI
326 case SAB_CRYPTO_KASUMI:
327 SAState_p->CipherKeyWords = 4;
328 SAState_p->IVWords = 0;
329 SAState_p->CW0 |= SAB_CW0_CRYPTO_KASUMI;
330 break;
331#endif
332#ifdef SAB_ENABLE_CRYPTO_SNOW
333 case SAB_CRYPTO_SNOW:
334 SAState_p->CipherKeyWords = 4;
335 SAState_p->IVWords = 4;
336 SAState_p->CW0 |= SAB_CW0_CRYPTO_SNOW;
337 break;
338#endif
339#ifdef SAB_ENABLE_CRYPTO_ZUC
340 case SAB_CRYPTO_ZUC:
341 SAState_p->CipherKeyWords = 4;
342 SAState_p->IVWords = 4;
343 SAState_p->CW0 |= SAB_CW0_CRYPTO_ZUC;
344 break;
345#endif
346#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
347 case SAB_CRYPTO_CHACHA20:
348 SAState_p->CW0 |= SAB_CW0_CRYPTO_CHACHA20;
349 switch (SAParams_p->KeyByteCount)
350 {
351 case 16:
352 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA128;
353 SAState_p->CipherKeyWords = 4;
354 break;
355 case 32:
356 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA256;
357 SAState_p->CipherKeyWords = 8;
358 break;
359 default:
360 LOG_CRIT("SABuilder: Bad key size for Chacha20.\n");
361 return SAB_INVALID_PARAMETER;
362 }
363 break;
364#endif
365 default:
366 LOG_CRIT("SABuilder: Unsupported crypto algorithm\n");
367 return SAB_UNSUPPORTED_FEATURE;
368 }
369
370 /* Check block cipher length against provided key */
371 if (SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
372 SAState_p->CipherKeyWords*sizeof(uint32_t) != SAParams_p->KeyByteCount)
373 {
374 LOG_CRIT("SABuilder: Bad cipher key size..\n");
375 return SAB_INVALID_PARAMETER;
376 }
377
378#ifdef SAB_STRICT_ARGS_CHECK
379 if ( SAState_p->CipherKeyWords > 0 && SAParams_p->Key_p == NULL)
380 {
381 LOG_CRIT("SABuilder: NULL pointer for Key_p.\n");
382 return SAB_INVALID_PARAMETER;
383 }
384#endif
385
386#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
387 if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20 &&
388 SAParams_p->KeyByteCount == 16)
389 {
390 /* Copy the key twice for 128-bit Chacha20 */
391 SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
392 SAParams_p->Key_p, SAParams_p->KeyByteCount);
393 SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
394 }
395#endif
396 /* Copy the cipher key */
397 SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
398 SAParams_p->Key_p, SAParams_p->KeyByteCount);
399
400 if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR)
401 SAState_p->CurrentOffset += 4; /* Always use 4 words for key in ARC4*/
402 else
403 SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
404
405 /* Check that wireless algorithms are not used with authentication */
406 if ((SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI ||
407 SAParams_p->CryptoAlgo == SAB_CRYPTO_SNOW ||
408 SAParams_p->CryptoAlgo == SAB_CRYPTO_ZUC) &&
409 SAParams_p->AuthAlgo != SAB_AUTH_NULL)
410 {
411 LOG_CRIT("SABuilder: "
412 "Crypto algorithm cannot be combined with authentication.\n");
413 return SAB_INVALID_PARAMETER;
414 }
415
416 /* Handle feedback modes */
417 if (SAParams_p->CryptoAlgo == SAB_CRYPTO_DES ||
418 SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES ||
419 SAParams_p->CryptoAlgo == SAB_CRYPTO_AES ||
420 SAParams_p->CryptoAlgo == SAB_CRYPTO_SM4 ||
421 SAParams_p->CryptoAlgo == SAB_CRYPTO_BC0)
422 {
423 switch (SAParams_p->CryptoMode)
424 {
425 case SAB_CRYPTO_MODE_ECB:
426 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_ECB;
427 SAState_p->IVWords = 0;
428 break;
429 case SAB_CRYPTO_MODE_CBC:
430 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CBC;
431 break;
432 case SAB_CRYPTO_MODE_CFB:
433 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CFB;
434 break;
435 case SAB_CRYPTO_MODE_OFB:
436 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_OFB;
437 break;
438 case SAB_CRYPTO_MODE_CTR:
439 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
440 break;
441 case SAB_CRYPTO_MODE_ICM:
442 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_ICM;
443 break;
444 case SAB_CRYPTO_MODE_CCM:
445 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
446 if (SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM)
447 {
448 LOG_CRIT("SABuilder: crypto CCM requires auth CCM.\n");
449 return SAB_INVALID_PARAMETER;
450 }
451 break;
452 case SAB_CRYPTO_MODE_GCM:
453 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
454 if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM)
455 {
456 LOG_CRIT("SABuilder: crypto GCM requires auth GCM.\n");
457 return SAB_INVALID_PARAMETER;
458 }
459 break;
460 case SAB_CRYPTO_MODE_GMAC:
461 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
462 if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC)
463 {
464 LOG_CRIT("SABuilder: crypto GMAC requires auth GMAC.\n");
465 return SAB_INVALID_PARAMETER;
466 }
467 break;
468#ifdef SAB_ENABLE_CRYPTO_XTS
469 case SAB_CRYPTO_MODE_XTS:
470 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_XTS;
471 if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
472 {
473 LOG_CRIT("SABuilder: crypto AES-XTS requires auth NULL.\n");
474 return SAB_INVALID_PARAMETER;
475 }
476 break;
477 case SAB_CRYPTO_MODE_XTS_STATEFUL:
478 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_XTS | SAB_CW1_XTS_STATEFUL;
479 if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
480 {
481 LOG_CRIT("SABuilder: crypto AES-XTS requires auth NULL.\n");
482 return SAB_INVALID_PARAMETER;
483 }
484 break;
485#endif
486 default:
487 LOG_CRIT("SABuilder: Invalid crypto mode.\n");
488 return SAB_INVALID_PARAMETER;
489 }
490 }
491 else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI ||
492 SAParams_p->CryptoAlgo == SAB_CRYPTO_SNOW ||
493 SAParams_p->CryptoAlgo == SAB_CRYPTO_ZUC)
494 {
495 if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_F8 ||
496 SAParams_p->CryptoMode == SAB_CRYPTO_MODE_UEA2 ||
497 SAParams_p->CryptoMode == SAB_CRYPTO_MODE_EEA3)
498
499 {
500 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_F8_UEA;
501 }
502 else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_BASIC ||
503 SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ECB)
504 {
505 // Do nothing.
506 }
507 else
508 {
509 LOG_CRIT("SABuilder: Invalid crypto mode for wireless .\n");
510 return SAB_INVALID_PARAMETER;
511 }
512 }
513
514#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
515 else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
516 {
517 SAState_p->IVWords = 4;
518 if (SAParams_p->AuthAlgo == SAB_AUTH_POLY1305 ||
519 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_POLY1305)
520 {
521 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR32 |
522 SAB_CW1_CRYPTO_AEAD;
523 }
524 else if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
525 {
526 if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR64)
527 {
528 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR64;
529 }
530 else
531 {
532 SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR32;
533 }
534 }
535 else
536 {
537 LOG_CRIT("SABuilder: Invalid authentication mode for Chacha20 .\n");
538 return SAB_INVALID_PARAMETER;
539 }
540 }
541#endif
542
543 /* The following crypto modes can only be used with AES */
544 if ( (SAParams_p->CryptoMode==SAB_CRYPTO_MODE_CCM ||
545 SAParams_p->CryptoMode==SAB_CRYPTO_MODE_GCM ||
546 SAParams_p->CryptoMode==SAB_CRYPTO_MODE_GMAC ||
547 SAParams_p->CryptoMode==SAB_CRYPTO_MODE_XTS ||
548 SAParams_p->CryptoMode==SAB_CRYPTO_MODE_XTS_STATEFUL) &&
549 SAParams_p->CryptoAlgo != SAB_CRYPTO_AES)
550 {
551 LOG_CRIT("SABuilder: crypto mode requires AES.\n");
552 return SAB_INVALID_PARAMETER;
553 }
554 /* The following crypto modes can only be used with AES or SM4 */
555 if ( (SAParams_p->CryptoMode==SAB_CRYPTO_MODE_CTR ||
556 SAParams_p->CryptoMode==SAB_CRYPTO_MODE_ICM) &&
557 SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
558 SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
559 SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0)
560 {
561 LOG_CRIT("SABuilder: crypto mode requires AES or SM4.\n");
562 return SAB_INVALID_PARAMETER;
563 }
564
565 return SAB_STATUS_OK;
566}
567
568
569/*----------------------------------------------------------------------------
570 * SABuilder_SetAuthSizeAndMode
571 *
572 * Determine the size of the authentication keys and set the required mode
573 * bits in the control words.
574 *
575 * SAParams_p (input)
576 * The SA parameters structure from which the SA is derived.
577 *
578 * SAState_p (input, output)
579 * Variables containing information about the SA being generated.
580 *
581 * Auth1Words_p (output)
582 * The number of 32-bit words of the first authentication key.
583 *
584 * Auth2Words_p (output)
585 * The number of 32-bit words of the second authentication key.
586 *
587 * Return:
588 * SAB_STATUS_OK on success
589 * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
590 * the buffer arguments is a null pointer while the corresponding buffer
591 * would be required for the operation.
592 * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
593 * is not supported on the hardware for which this SA builder
594 * is configured.
595 */
596static SABuilder_Status_t
597SABuilder_SetAuthSizeAndMode(
598 SABuilder_Params_t *const SAParams_p,
599 SABuilder_State_t * const SAState_p,
600 uint32_t * const Auth1Words_p,
601 uint32_t * const Auth2Words_p)
602{
603 unsigned int Auth1Words = 0;
604 unsigned int Auth2Words = 0;
605
606 switch (SAParams_p->AuthAlgo)
607 {
608 case SAB_AUTH_NULL:
609 break;
610#ifdef SAB_ENABLE_AUTH_MD5
611 case SAB_AUTH_HASH_MD5:
612 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_MD5;
613 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
614 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
615 {
616 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
617 Auth1Words = 4;
618 }
619 break;
620#endif
621#ifdef SAB_ENABLE_AUTH_SHA1
622 case SAB_AUTH_HASH_SHA1:
623 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA1;
624 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
625 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
626 {
627 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
628 Auth1Words = 5;
629 }
630 break;
631#endif
632#ifdef SAB_ENABLE_AUTH_SHA2_256
633 case SAB_AUTH_HASH_SHA2_224:
634 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_224;
635 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
636 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
637 {
638 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
639 Auth1Words = 8;
640 }
641 break;
642 case SAB_AUTH_HASH_SHA2_256:
643 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_256;
644 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
645 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
646 {
647 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
648 Auth1Words = 8;
649 }
650 break;
651#endif
652#ifdef SAB_ENABLE_AUTH_SHA2_512
653 case SAB_AUTH_HASH_SHA2_384:
654 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_384;
655 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
656 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
657 {
658 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
659 Auth1Words = 16;
660 }
661 break;
662 case SAB_AUTH_HASH_SHA2_512:
663 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_512;
664 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
665 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
666 {
667 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
668 Auth1Words = 16;
669 }
670 break;
671#endif
672#ifdef SAB_ENABLE_AUTH_SHA3
673 case SAB_AUTH_HASH_SHA3_224:
674 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_224;
675 if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
676 {
677 Auth1Words = 36;
678 }
679 break;
680 case SAB_AUTH_HASH_SHA3_256:
681 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_256;
682 if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
683 {
684 Auth1Words = 34;
685 }
686 break;
687 case SAB_AUTH_HASH_SHA3_384:
688 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_384;
689 if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
690 {
691 Auth1Words = 26;
692 }
693 break;
694 case SAB_AUTH_HASH_SHA3_512:
695 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_512;
696 if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
697 {
698 Auth1Words = 18;
699 }
700 break;
701#endif
702#ifdef SAB_ENABLE_AUTH_SM3
703 case SAB_AUTH_HASH_SM3:
704 SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SM3;
705 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
706 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
707 {
708 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
709 Auth1Words = 8;
710 }
711 break;
712#endif
713#ifdef SAB_ENABLE_AUTH_MD5
714 case SAB_AUTH_SSLMAC_MD5:
715 case SAB_AUTH_HMAC_MD5:
716 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_MD5;
717 Auth1Words = 4;
718 Auth2Words = 4;
719 break;
720#endif
721#ifdef SAB_ENABLE_AUTH_SHA1
722 case SAB_AUTH_SSLMAC_SHA1:
723 SAState_p->CW0 |= SAB_CW0_AUTH_SSLMAC_SHA1;
724 Auth1Words = 5;
725 break;
726 case SAB_AUTH_HMAC_SHA1:
727 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA1;
728 Auth1Words = 5;
729 Auth2Words = 5;
730 break;
731#endif
732#ifdef SAB_ENABLE_AUTH_SHA2_256
733 case SAB_AUTH_HMAC_SHA2_224:
734 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_224;
735 Auth1Words = 8;
736 Auth2Words = 8;
737 break;
738 case SAB_AUTH_HMAC_SHA2_256:
739 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_256;
740 Auth1Words = 8;
741 Auth2Words = 8;
742 break;
743#endif
744#ifdef SAB_ENABLE_AUTH_SHA2_512
745 case SAB_AUTH_HMAC_SHA2_384:
746 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_384;
747 Auth1Words = 16;
748 Auth2Words = 16;
749 break;
750 case SAB_AUTH_HMAC_SHA2_512:
751 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_512;
752 Auth1Words = 16;
753 Auth2Words = 16;
754 break;
755#endif
756#ifdef SAB_ENABLE_AUTH_SHA3
757 case SAB_AUTH_KEYED_HASH_SHA3_224:
758 SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_224;
759 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
760 Auth1Words = 36;
761 break;
762 case SAB_AUTH_KEYED_HASH_SHA3_256:
763 SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_256;
764 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
765 Auth1Words = 34;
766 break;
767 case SAB_AUTH_KEYED_HASH_SHA3_384:
768 SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_384;
769 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
770 Auth1Words = 26;
771 break;
772 case SAB_AUTH_KEYED_HASH_SHA3_512:
773 SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_512;
774 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
775 Auth1Words = 18;
776 break;
777 case SAB_AUTH_HMAC_SHA3_224:
778 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_224;
779 Auth1Words = 36;
780 break;
781 case SAB_AUTH_HMAC_SHA3_256:
782 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_256;
783 Auth1Words = 34;
784 break;
785 case SAB_AUTH_HMAC_SHA3_384:
786 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_384;
787 Auth1Words = 26;
788 break;
789 case SAB_AUTH_HMAC_SHA3_512:
790 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_512;
791 Auth1Words = 18;
792 break;
793#endif
794#ifdef SAB_ENABLE_AUTH_SM3
795 case SAB_AUTH_HMAC_SM3:
796 SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SM3;
797 Auth1Words = 8;
798 Auth2Words = 8;
799 break;
800#endif
801 case SAB_AUTH_AES_XCBC_MAC:
802 case SAB_AUTH_AES_CMAC_128:
803 SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_128;
804 Auth1Words = 4;
805 Auth2Words = 4;
806 break;
807 case SAB_AUTH_AES_CMAC_192:
808 SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_192;
809 Auth1Words = 6;
810 Auth2Words = 4;
811 break;
812 case SAB_AUTH_AES_CMAC_256:
813 SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_256;
814 Auth1Words = 8;
815 Auth2Words = 4;
816 break;
817 case SAB_AUTH_AES_CCM:
818 if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM)
819 {
820 LOG_CRIT("SABuilder: auth CCM requires crypto CCM.\n");
821 return SAB_INVALID_PARAMETER;
822 }
823 switch (SAParams_p->KeyByteCount)
824 {
825 case 16:
826 Auth1Words = 4;
827 SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_128;
828 break;
829 case 24:
830 Auth1Words = 6;
831 SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_192;
832 break;
833 case 32:
834 Auth1Words = 8;
835 SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_256;
836 break;
837 }
838 Auth2Words = 4;
839 SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
840 break;
841#ifdef SAB_ENABLE_CRYPTO_GCM
842 case SAB_AUTH_AES_GCM:
843 if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM)
844 {
845 LOG_CRIT("SABuilder: auth GCM requires crypto GCM.\n");
846 return SAB_INVALID_PARAMETER;
847 }
848 SAState_p->CW0 |= SAB_CW0_AUTH_GHASH;
849 Auth1Words = 4;
850 SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
851 break;
852 case SAB_AUTH_AES_GMAC:
853 if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GMAC)
854 {
855 LOG_CRIT("SABuilder: auth GMAC requires crypto GMAC.\n");
856 return SAB_INVALID_PARAMETER;
857 }
858 SAState_p->CW0 |= SAB_CW0_AUTH_GHASH;
859 Auth1Words = 4;
860 SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
861 break;
862#endif
863#ifdef SAB_ENABLE_CRYPTO_KASUMI
864 case SAB_AUTH_KASUMI_F9:
865 if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
866 {
867 LOG_CRIT("SABuilder: auth KASUMI requires crypto NULL.\n");
868 return SAB_INVALID_PARAMETER;
869 }
870 Auth1Words = 4;
871 SAState_p->CW0 |= SAB_CW0_AUTH_KASUMI_F9;
872 break;
873#endif
874#ifdef SAB_ENABLE_CRYPTO_SNOW
875 case SAB_AUTH_SNOW_UIA2:
876 if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
877 {
878 LOG_CRIT("SABuilder: auth SNOW requires crypto NULL.\n");
879 return SAB_INVALID_PARAMETER;
880 }
881 Auth1Words = 4;
882 SAState_p->CW0 |= SAB_CW0_AUTH_SNOW_UIA2;
883 break;
884#endif
885#ifdef SAB_ENABLE_CRYPTO_ZUC
886 case SAB_AUTH_ZUC_EIA3:
887 if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
888 {
889 LOG_CRIT("SABuilder: auth ZUC requires crypto NULL.\n");
890 return SAB_INVALID_PARAMETER;
891 }
892 Auth1Words = 4;
893 SAState_p->CW0 |= SAB_CW0_AUTH_ZUC_EIA3;
894 break;
895#endif
896#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
897 case SAB_AUTH_KEYED_HASH_POLY1305:
898 if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
899 {
900 LOG_CRIT("SABuilder: auth keyed Poly1305 requires crypto NULL.\n");
901 return SAB_INVALID_PARAMETER;
902 }
903 if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
904 SAB_FLAG_HASH_INTERMEDIATE)) != 0)
905 {
906 SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
907 Auth1Words = 4;
908 Auth2Words = 8;
909 }
910 else
911 {
912 Auth1Words = 8;
913 }
914 SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_POLY1305;
915 break;
916 case SAB_AUTH_POLY1305:
917 if (SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20)
918 {
919 LOG_CRIT("SABuilder: auth Poly1305 requires crypto Chacha20.\n");
920 return SAB_INVALID_PARAMETER;
921 }
922 SAState_p->CW0 |= SAB_CW0_AUTH_POLY1305;
923 SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_MODE_CHACHA_POLY_OTK;
924 SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
925 break;
926#endif
927 default:
928 LOG_CRIT("SABuilder: Unsupported authentication algorithm\n");
929 return SAB_UNSUPPORTED_FEATURE;
930 }
931
932 *Auth1Words_p = Auth1Words;
933 *Auth2Words_p = Auth2Words;
934 return SAB_STATUS_OK;
935}
936
937
938/*----------------------------------------------------------------------------
939 * SABuilder_SetAuthKeys
940 *
941 * Fill in authentication keys and associated command word fields in SA.
942 *
943 * SAParams_p (input)
944 * The SA parameters structure from which the SA is derived.
945 *
946 * SAState_p (input, output)
947 * Variables containing information about the SA being generated.
948 *
949 * SABuffer_p (input, output).
950 * The buffer in which the SA is built. If NULL, no SA will be built, but
951 * state variables in SAState_p will still be updated.
952 *
953 * Return:
954 * SAB_STATUS_OK on success
955 * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
956 * the buffer arguments is a null pointer while the corresponding buffer
957 * would be required for the operation.
958 * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
959 * is not supported on the hardware for which this SA builder
960 * is configured.
961 */
962static SABuilder_Status_t
963SABuilder_SetAuthKeys(
964 SABuilder_Params_t *const SAParams_p,
965 SABuilder_State_t * const SAState_p,
966 uint32_t * const SABuffer_p)
967{
968 unsigned int Auth1Words = 0;
969 unsigned int Auth2Words = 0;
970 SABuilder_Status_t Rc;
971
972 Rc = SABuilder_SetAuthSizeAndMode(SAParams_p,
973 SAState_p,
974 &Auth1Words,
975 &Auth2Words);
976 if (Rc != SAB_STATUS_OK)
977 {
978 return Rc;
979 }
980
981 /* Now copy the authentication keys, if applicable */
982 if (SAParams_p->AuthAlgo == SAB_AUTH_AES_CCM)
983 {
984 SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
985 SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 32);
986 /* Fill zero blocks for the XCBC MAC subkeys */
987 SAState_p->CurrentOffset += 8;
988 SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset,
989 SAParams_p->Key_p,
990 SAParams_p->KeyByteCount);
991 SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
992
993 if (SAState_p->CipherKeyWords == 6)
994 {
995 SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 8);
996 SAState_p->CurrentOffset += 2; /* Pad key to 256 bits for CCM-192*/
997 }
998 }
999 else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_XCBC_MAC ||
1000 SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_128 ||
1001 SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_192 ||
1002 SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_256)
1003 {
1004#ifdef SAB_STRICT_ARGS_CHECK
1005 if (SAParams_p->AuthKey1_p == NULL ||
1006 SAParams_p->AuthKey2_p == NULL ||
1007 SAParams_p->AuthKey3_p == NULL)
1008 {
1009 LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
1010 return SAB_INVALID_PARAMETER;
1011 }
1012#endif
1013 SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
1014 SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset,
1015 SAParams_p->AuthKey2_p,
1016 4 * sizeof(uint32_t));
1017 SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset + 4,
1018 SAParams_p->AuthKey3_p,
1019 4 * sizeof(uint32_t));
1020 SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset + 8,
1021 SAParams_p->AuthKey1_p,
1022 Auth1Words * sizeof(uint32_t));
1023 SAState_p->CurrentOffset += 8 + Auth1Words;
1024 if (Auth1Words == 6)
1025 {
1026 SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 8);
1027 SAState_p->CurrentOffset += 2; /* Pad key to 256 bits for CMAC-192*/
1028 }
1029 }
1030#ifdef SAB_ENABLE_AUTH_SHA3
1031 else if (SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_224 ||
1032 SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_256 ||
1033 SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_384 ||
1034 SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_512 ||
1035 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_224 ||
1036 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_256 ||
1037 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_384 ||
1038 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_512 ||
1039 SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_224 ||
1040 SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_256 ||
1041 SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_384 ||
1042 SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_512)
1043 {
1044#ifdef SAB_STRICT_ARGS_CHECK
1045 if (Auth1Words > 0)
1046 {
1047 if (SAParams_p->AuthKey1_p == NULL &&
1048 SAParams_p->AuthKeyByteCount > 0)
1049 {
1050 LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
1051 return SAB_INVALID_PARAMETER;
1052 }
1053 if (SAParams_p->AuthKeyByteCount > Auth1Words * sizeof(uint32_t))
1054 {
1055 LOG_CRIT("SABuilder: Authentication key too long\n");
1056 return SAB_INVALID_PARAMETER;
1057 }
1058#endif
1059 SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
1060 SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
1061 Auth1Words * sizeof(uint32_t));
1062
1063 SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
1064 SAParams_p->AuthKey1_p,
1065 SAParams_p->AuthKeyByteCount);
1066
1067 SAState_p->CurrentOffset += Auth1Words;
1068
1069 if (SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_224 ||
1070 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_256 ||
1071 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_384 ||
1072 SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_512)
1073 {
1074 if (SAParams_p->AuthKeyByteCount <
1075 Auth1Words * sizeof(uint32_t))
1076 {
1077 // Put the key length in last byte of key if it is smaller
1078 // than the maximum.
1079 SAState_p->CW1 |= SAB_CW1_DIGEST_CNT;
1080 if (SABuffer_p != NULL)
1081 {
1082 SABuffer_p[SAState_p->CurrentOffset - 1] |=
1083 (SAParams_p->AuthKeyByteCount << 24);
1084 }
1085 }
1086 }
1087 }
1088 }
1089#endif
1090 else if(Auth1Words > 0 && Auth2Words > 0 &&
1091 SAParams_p->AuthKey1_p == NULL && SAParams_p->AuthKey2_p == NULL)
1092 {
1093 /* HMAC precomputes not given, allow later computation of
1094 precomputes. */
1095 SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
1096 SAParams_p->OffsetDigest1 = SAState_p->CurrentOffset + Auth1Words;
1097 SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
1098 (Auth1Words + Auth2Words) * sizeof(uint32_t));
1099 SAState_p->CurrentOffset += Auth1Words + Auth2Words;
1100 }
1101 else
1102 {
1103 if (Auth1Words > 0)
1104 {
1105#ifdef SAB_STRICT_ARGS_CHECK
1106 if (SAParams_p->AuthKey1_p == NULL)
1107 {
1108 LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
1109 return SAB_INVALID_PARAMETER;
1110 }
1111#endif
1112 SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
1113 SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
1114 SAParams_p->AuthKey1_p,
1115 Auth1Words * sizeof(uint32_t));
1116 SAState_p->CurrentOffset += Auth1Words;
1117
1118 if (SAParams_p->AuthAlgo == SAB_AUTH_SSLMAC_SHA1)
1119 { /* both inner and outer digest fields must be set, even though
1120 only one is used. */
1121 SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
1122 Auth1Words * sizeof(uint32_t));
1123 SAState_p->CurrentOffset += Auth1Words;
1124 }
1125 }
1126 if (Auth2Words > 0)
1127 {
1128#ifdef SAB_STRICT_ARGS_CHECK
1129 if (SAParams_p->AuthKey2_p == NULL)
1130 {
1131 LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
1132 return SAB_INVALID_PARAMETER;
1133 }
1134#endif
1135 SAParams_p->OffsetDigest1 = SAState_p->CurrentOffset;
1136 SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
1137 SAParams_p->AuthKey2_p,
1138 Auth2Words * sizeof(uint32_t));
1139 SAState_p->CurrentOffset += Auth2Words;
1140 }
1141 }
1142
1143 return SAB_STATUS_OK;
1144}
1145
1146
1147
1148/*----------------------------------------------------------------------------
1149 * SABuilder_GetSizes
1150 *
1151 * Compute the required sizes in 32-bit words of any of up to three memory
1152 * areas used by the SA.
1153 *
1154 * SAParams_p (input)
1155 * Pointer to the SA parameters structure.
1156 *
1157 * SAWord32Count_p (output)
1158 * The size of the normal SA buffer.
1159 *
1160 * SAStateWord32Count_p (output)
1161 * The size of any SA state record.
1162 *
1163 * ARC4StateWord32Count_p (output) T
1164 * The size of any ARCFOUR state buffer (output).
1165 *
1166 * When the SA state record or ARCFOUR state buffer are not required by
1167 * the packet engine for this transform, the corresponding size outputs
1168 * are returned as zero. The Security-IP-96 never requires these buffers
1169 *
1170 * If any of the output parameters is a null pointer,
1171 * the corresponding size will not be returned.
1172 *
1173 * The SAParams_p structure must be fully filled in: it must have the
1174 * same contents as it would have when SABuilder_BuildSA is called.
1175 * This function calls the same routines as SABuilder_BuildSA, but with
1176 * null pointers instead of the SA pointer, so no actual SA will be built.
1177 * These functions are only called to obtain the length of the SA.
1178 *
1179 * Return:
1180 * SAB_STATUS_OK on success
1181 * SAB_INVALID_PARAMETER when the record referenced by SAParams_p is invalid,
1182 */
1183SABuilder_Status_t
1184SABuilder_GetSizes(
1185 SABuilder_Params_t *const SAParams_p,
1186 unsigned int *const SAWord32Count_p,
1187 unsigned int *const SAStateWord32Count_p,
1188 unsigned int *const ARC4StateWord32Count_p)
1189{
1190 SABuilder_State_t SAState;
1191 int rc;
1192
1193#ifdef SAB_STRICT_ARGS_CHECK
1194 if (SAParams_p == NULL)
1195 {
1196 LOG_CRIT("SABuilder_GetSizes: NULL pointer SAParams_p supplied\n");
1197 return SAB_INVALID_PARAMETER;
1198 }
1199#endif
1200
1201 SAState.CurrentOffset = 2; /* Count Control words 0 and 1 */
1202 SAState.CW0 = 0;
1203 SAState.CW1 = 0;
1204 SAState.CipherKeyWords = 0;
1205 SAState.IVWords = 0;
1206 SAState.ARC4State = false;
1207 SAState.fLarge = false;
1208 SAState.fLargeMask = false;
1209
1210 rc = SABuilder_SetCipherKeys(SAParams_p, &SAState, NULL);
1211 if (rc != SAB_STATUS_OK)
1212 return rc;
1213
1214 rc = SABuilder_SetAuthKeys(SAParams_p, &SAState, NULL);
1215 if (rc != SAB_STATUS_OK)
1216 return rc;
1217
1218 switch ( SAParams_p->protocol)
1219 {
1220#ifdef SAB_ENABLE_PROTO_BASIC
1221 case SAB_PROTO_BASIC:
1222 {
1223 rc = SABuilder_SetBasicParams(SAParams_p, &SAState, NULL);
1224 }
1225 break;
1226#endif
1227#ifdef SAB_ENABLE_PROTO_IPSEC
1228 case SAB_PROTO_IPSEC:
1229 {
1230 rc = SABuilder_SetIPsecParams(SAParams_p, &SAState, NULL);
1231 }
1232 break;
1233#endif
1234#ifdef SAB_ENABLE_PROTO_SSLTLS
1235 case SAB_PROTO_SSLTLS:
1236 {
1237 rc = SABuilder_SetSSLTLSParams(SAParams_p, &SAState, NULL);
1238 }
1239 break;
1240#endif
1241#ifdef SAB_ENABLE_PROTO_SRTP
1242 case SAB_PROTO_SRTP:
1243 {
1244 rc = SABuilder_SetSRTPParams(SAParams_p, &SAState, NULL);
1245 }
1246 break;
1247#endif
1248#ifdef SAB_ENABLE_PROTO_MACSEC
1249 case SAB_PROTO_MACSEC:
1250 {
1251 rc = SABuilder_SetMACsecParams(SAParams_p, &SAState, NULL);
1252 }
1253 break;
1254#endif
1255 default:
1256 LOG_CRIT("SABuilder_GetSizes: unsupported protocol\n");
1257 return SAB_INVALID_PARAMETER;
1258 }
1259 if (rc != SAB_STATUS_OK)
1260 return rc;
1261
1262 if (SAState.ARC4State)
1263 {
1264 SAState.CurrentOffset += 2; /* Count IJ pointer and ARC4 State */
1265 }
1266
1267 if (SAState.CurrentOffset == 2)
1268 {
1269 SAState.CurrentOffset += 1;
1270 /* Make sure to have at least one non-context word */
1271 }
1272
1273#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
1274#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
1275#ifdef SAB_ENABLE_IPSEC_EXTENDED
1276 /* It is possible that a record will have to be
1277 large because of options used by firmware, so determine if the record
1278 needs to be large. */
1279 if (SAParams_p->protocol == SAB_PROTO_IPSEC)
1280 {
1281 SABuilder_Status_t res;
1282 res = SABuilder_SetExtendedIPsecParams(SAParams_p,
1283 &SAState,
1284 NULL);
1285 if (res != SAB_STATUS_OK)
1286 return res;
1287 }
1288#endif
1289#ifdef SAB_ENABLE_DTLS_EXTENDED
1290 if (SAParams_p->protocol == SAB_PROTO_SSLTLS)
1291 {
1292 SABuilder_Status_t res;
1293 res = SABuilder_SetExtendedDTLSParams(SAParams_p, &SAState, NULL);
1294 if (res != SAB_STATUS_OK)
1295 return res;
1296 }
1297#endif
1298#ifdef SAB_ENABLE_MACSEC_EXTENDED
1299 if (SAParams_p->protocol == SAB_PROTO_MACSEC)
1300 {
1301 SABuilder_Status_t res;
1302 res = SABuilder_SetExtendedMACsecParams(SAParams_p,
1303 &SAState,
1304 NULL);
1305 if (res != SAB_STATUS_OK)
1306 return res;
1307 }
1308#endif
1309#ifdef SAB_ENABLE_BASIC_EXTENDED
1310 if (SAParams_p->protocol == SAB_PROTO_BASIC)
1311 {
1312 SABuilder_Status_t res;
1313 res = SABuilder_SetExtendedBasicParams(SAParams_p,
1314 &SAState,
1315 NULL);
1316 if (res != SAB_STATUS_OK)
1317 return res;
1318 }
1319#endif
1320 if (SAParams_p->OffsetSeqNum <= SAB_SEQNUM_LO_FIX_OFFSET &&
1321 !SAState.fLarge)
1322 {
1323 SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
1324 }
1325 else if (SAState.CurrentOffset <= SAB_RECORD_WORD_COUNT + LargeTransformOffset)
1326 {
1327 SAState.CurrentOffset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
1328 }
1329 else
1330 {
1331 LOG_CRIT("SABuilder_GetSizes: SA filled beyond record size.\n");
1332 return SAB_INVALID_PARAMETER;
1333 }
1334#else
1335 if (SAState.CurrentOffset > SAB_RECORD_WORD_COUNT)
1336 {
1337 LOG_CRIT("SABuilder_GetSizes: SA filled beyond record size.\n");
1338 return SAB_INVALID_PARAMETER;
1339 }
1340 SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
1341 /* Make the SA record a fixed size for engines that have
1342 record caches */
1343#endif
1344#endif
1345
1346 if (SAStateWord32Count_p != NULL)
1347 *SAStateWord32Count_p = 0;
1348
1349#ifdef SAB_ARC4_STATE_IN_SA
1350 if (ARC4StateWord32Count_p != NULL)
1351 *ARC4StateWord32Count_p = 0;
1352 if (SAState.ARC4State)
1353 {
1354 if (SAParams_p->OffsetARC4StateRecord > 0)
1355 {
1356 if (SAParams_p->OffsetARC4StateRecord < SAState.CurrentOffset)
1357 {
1358 LOG_CRIT("SABuilder_GetSizes: OffsetARC4StateRecord too low\n");
1359 return SAB_INVALID_PARAMETER;
1360 }
1361 SAState.CurrentOffset = SAParams_p->OffsetARC4StateRecord + 64;
1362 }
1363 else
1364 {
1365 SAState.CurrentOffset =
1366 SABuilder_AlignForARc4State(SAState.CurrentOffset);
1367 SAState.CurrentOffset += 64;
1368 }
1369 }
1370#else
1371 if (ARC4StateWord32Count_p != NULL)
1372 {
1373 if (SAState.ARC4State)
1374 {
1375 *ARC4StateWord32Count_p = 64;
1376 }
1377 else
1378 {
1379 *ARC4StateWord32Count_p = 0;
1380 }
1381 }
1382#endif
1383#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
1384 {
1385 TokenBuilder_Status_t rc;
1386 unsigned int ContextSize;
1387 rc = TokenBuilder_GetContextSize(SAParams_p, &ContextSize);
1388 if (rc != TKB_STATUS_OK)
1389 {
1390 return SAB_ERROR;
1391 }
1392 SAState.CurrentOffset += ContextSize;
1393 }
1394#endif
1395 if (SAWord32Count_p != NULL)
1396 *SAWord32Count_p = SAState.CurrentOffset;
1397
1398 return SAB_STATUS_OK;
1399}
1400
1401/*----------------------------------------------------------------------------
1402 * SABuilder_BuildSA
1403 *
1404 * Construct the SA record for the operation described in SAParams_p in
1405 * up to three memory buffers.
1406 *
1407 * SAParams_p (input)
1408 * Pointer to the SA parameters structure.
1409 *
1410 * SABuffer_p (output)
1411 * Pointer to the the normal SA buffer.
1412 *
1413 * SAStateBuffer_p (output)
1414 * Pointer to the SA state record buffer.
1415 *
1416 * ARC4StateBuffer_p (output)
1417 * Pointer to the ARCFOUR state buffer.
1418 *
1419 * Each of the Buffer arguments must point to a word-aligned
1420 * memory buffer whose size in words is at least equal to the
1421 * corresponding size parameter returned by SABuilder_GetSizes().
1422 *
1423 * If any of the three buffers is not required for the SA (the
1424 * corresponding size in SABuilder_GetSizes() is 0), the corresponding
1425 * Buffer arguments to this function may be a null pointer.
1426 * The Security-IP-96 never requires these buffers.
1427 *
1428 * Return:
1429 * SAB_STATUS_OK on success
1430 * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
1431 * the buffer arguments is a null pointer while the corresponding buffer
1432 * would be required for the operation.
1433 * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
1434 * is not supported on the hardware for which this SA builder
1435 * is configured.
1436 */
1437SABuilder_Status_t
1438SABuilder_BuildSA(
1439 SABuilder_Params_t * const SAParams_p,
1440 uint32_t *const SABuffer_p,
1441 uint32_t *const SAStateBuffer_p,
1442 uint32_t *const ARC4StateBuffer_p)
1443{
1444 SABuilder_State_t SAState;
1445 int rc;
1446
1447 IDENTIFIER_NOT_USED(SAStateBuffer_p);
1448 IDENTIFIER_NOT_USED(ARC4StateBuffer_p);
1449
1450#ifdef SAB_STRICT_ARGS_CHECK
1451 if (SAParams_p == NULL || SABuffer_p == NULL)
1452 {
1453 LOG_CRIT("SABuilder: NULL pointer parameter supplied.\n");
1454 return SAB_INVALID_PARAMETER;
1455 }
1456#endif
1457
1458 SAState.CurrentOffset = 2; /* Count Control words 0 and 1 */
1459 SAState.CW0 = 0;
1460 SAState.CW1 = 0;
1461 SAState.CipherKeyWords = 0;
1462 SAState.IVWords = 0;
1463 SAState.ARC4State = false;
1464 SAState.fLarge = false;
1465 SAState.fLargeMask = false;
1466
1467 rc = SABuilder_SetCipherKeys(SAParams_p, &SAState, SABuffer_p);
1468 if (rc != SAB_STATUS_OK)
1469 return rc;
1470
1471 rc = SABuilder_SetAuthKeys(SAParams_p, &SAState, SABuffer_p);
1472 if (rc != SAB_STATUS_OK)
1473 return rc;
1474
1475 switch ( SAParams_p->protocol)
1476 {
1477#ifdef SAB_ENABLE_PROTO_BASIC
1478 case SAB_PROTO_BASIC:
1479 {
1480 rc = SABuilder_SetBasicParams(SAParams_p, &SAState, SABuffer_p);
1481 }
1482 break;
1483#endif
1484#ifdef SAB_ENABLE_PROTO_IPSEC
1485 case SAB_PROTO_IPSEC:
1486 {
1487 rc = SABuilder_SetIPsecParams(SAParams_p, &SAState, SABuffer_p);
1488 }
1489 break;
1490#endif
1491#ifdef SAB_ENABLE_PROTO_SSLTLS
1492 case SAB_PROTO_SSLTLS:
1493 {
1494 rc = SABuilder_SetSSLTLSParams(SAParams_p, &SAState, SABuffer_p);
1495 }
1496 break;
1497#endif
1498#ifdef SAB_ENABLE_PROTO_SRTP
1499 case SAB_PROTO_SRTP:
1500 {
1501 rc = SABuilder_SetSRTPParams(SAParams_p, &SAState, SABuffer_p);
1502 }
1503 break;
1504#endif
1505#ifdef SAB_ENABLE_PROTO_MACSEC
1506 case SAB_PROTO_MACSEC:
1507 {
1508 rc = SABuilder_SetMACsecParams(SAParams_p, &SAState, SABuffer_p);
1509 }
1510 break;
1511#endif
1512 default:
1513 LOG_CRIT("SABuilder_BuildSA: unsupported protocol\n");
1514 return SAB_UNSUPPORTED_FEATURE;
1515 }
1516 if (rc != SAB_STATUS_OK)
1517 return rc;
1518
1519#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
1520#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
1521 if (SAParams_p->OffsetSeqNum > SAB_SEQNUM_LO_FIX_OFFSET)
1522 SAState.fLarge = true;
1523#endif
1524#endif
1525
1526 if (SAState.ARC4State)
1527 {
1528 unsigned int ARC4Offset = 0;
1529#ifdef SAB_ARC4_STATE_IN_SA
1530 if (SAParams_p->OffsetARC4StateRecord > 0)
1531 {
1532 ARC4Offset = SAParams_p->OffsetARC4StateRecord;
1533 }
1534 else
1535 {
1536#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
1537#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
1538 if (SAState.fLarge)
1539 {
1540 ARC4Offset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
1541 }
1542 else
1543#else
1544 {
1545 ARC4Offset = SAB_RECORD_WORD_COUNT;
1546 }
1547#endif
1548#else
1549 ARC4Offset = SAState.CurrentOffset + 2;
1550#endif
1551 ARC4Offset = SABuilder_AlignForARc4State(ARC4Offset);
1552 }
1553#endif
1554 SABuffer_p[SAState.CurrentOffset] = ARC4Offset * sizeof(uint32_t);
1555 SABuffer_p[SAState.CurrentOffset + 1] = 0;
1556
1557 if ( (SAParams_p->flags & SAB_FLAG_ARC4_STATE_LOAD) != 0)
1558 {
1559 /* Load the ARC4 state when building the SA.
1560 Nonce_p[0] is the 'i' variable and
1561 Nonce_p[1] is the 'j' variable.
1562 IV_p points to the 256-byte state array.
1563 The SA Builder will not fill in the ARC4 state pointer. */
1564 if (SAParams_p->Nonce_p != NULL)
1565 {
1566 SABuffer_p[SAState.CurrentOffset + 1] =
1567 ((SAParams_p->Nonce_p[0] + 1) & 0xff) |
1568 (SAParams_p->Nonce_p[1]<<8);
1569 }
1570 if(SAParams_p->IV_p != NULL)
1571 {
1572#ifdef SAB_ARC4_STATE_IN_SA
1573 SABuilderLib_CopyKeyMat(SABuffer_p,
1574 (SAParams_p->OffsetARC4StateRecord >0 ?
1575 SAParams_p->OffsetARC4StateRecord :
1576 ARC4Offset),
1577 SAParams_p->IV_p,
1578 256);
1579
1580#else
1581 SABuilderLib_CopyKeyMat(ARC4StateBuffer_p,
1582 0,
1583 SAParams_p->IV_p,
1584 256);
1585#endif
1586 }
1587
1588 }
1589
1590 SAParams_p->OffsetIJPtr = SAState.CurrentOffset + 1;
1591 SAParams_p->OffsetARC4State = SAState.CurrentOffset;
1592
1593 SAState.CurrentOffset += 2; /* Count IJ pointer and ARC4 State */
1594 }
1595
1596 if (SAState.CurrentOffset == 2)
1597 {
1598 SABuffer_p[SAState.CurrentOffset++] = 0;
1599 /* Make sure to have at least one non-context word */
1600 }
1601
1602 if (!SAState.fLargeMask)
1603 SAState.CW0 |= (SAState.CurrentOffset - 2) << 8;
1604 else
1605 SAState.CW0 |= (SAState.CurrentOffset == 66)? 0x0200 : 0x0300;
1606
1607 SABuffer_p[0] = SAState.CW0;
1608 SABuffer_p[1] = SAState.CW1;
1609
1610 SAParams_p->CW0 = SAState.CW0;
1611 SAParams_p->CW1 = SAState.CW1;
1612
1613#ifdef SAB_ENABLE_IPSEC_EXTENDED
1614 if (SAParams_p->protocol == SAB_PROTO_IPSEC)
1615 {
1616 SABuilder_Status_t res;
1617 res = SABuilder_SetExtendedIPsecParams(SAParams_p,
1618 &SAState,
1619 SABuffer_p);
1620 if (res != SAB_STATUS_OK)
1621 return res;
1622 }
1623#endif
1624#ifdef SAB_ENABLE_DTLS_EXTENDED
1625 if (SAParams_p->protocol == SAB_PROTO_SSLTLS)
1626 {
1627 SABuilder_Status_t res;
1628 res = SABuilder_SetExtendedDTLSParams(SAParams_p, &SAState, SABuffer_p);
1629 if (res != SAB_STATUS_OK)
1630 return res;
1631 }
1632#endif
1633#ifdef SAB_ENABLE_MACSEC_EXTENDED
1634 if (SAParams_p->protocol == SAB_PROTO_MACSEC)
1635 {
1636 SABuilder_Status_t res;
1637 res = SABuilder_SetExtendedMACsecParams(SAParams_p,
1638 &SAState,
1639 SABuffer_p);
1640 if (res != SAB_STATUS_OK)
1641 return res;
1642 }
1643#endif
1644#ifdef SAB_ENABLE_BASIC_EXTENDED
1645 if (SAParams_p->protocol == SAB_PROTO_BASIC)
1646 {
1647 SABuilder_Status_t res;
1648 res = SABuilder_SetExtendedBasicParams(SAParams_p,
1649 &SAState,
1650 SABuffer_p);
1651 if (res != SAB_STATUS_OK)
1652 return res;
1653 }
1654#endif
1655
1656#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
1657#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
1658 if (SAState.fLarge)
1659 {
1660 SABuffer_p[0] |= SAB_CW0_SW_IS_LARGE;
1661#ifdef SAB_ENABLE_IPSEC_EXTENDED
1662 /* Must be set independent of protocol */
1663 if ((SAParams_p->flags & SAB_FLAG_REDIRECT) != 0)
1664 {
1665 SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
1666 LargeTransformOffset] |=
1667 BIT_11 | ((SAParams_p->RedirectInterface & MASK_4_BITS) << 12);
1668 }
1669#endif
1670 SAState.CurrentOffset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
1671 }
1672 else
1673 {
1674#ifdef SAB_ENABLE_IPSEC_EXTENDED
1675 /* Must be set independent of protocol */
1676 if ((SAParams_p->flags & SAB_FLAG_REDIRECT) != 0)
1677 {
1678 SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] |=
1679 BIT_11 | ((SAParams_p->RedirectInterface & MASK_4_BITS) << 12);
1680 }
1681#endif
1682 SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
1683 }
1684#endif
1685#endif
1686
1687#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
1688 {
1689 TokenBuilder_Status_t rc;
1690 void *TokenContext_p = (void*)&SABuffer_p[SAState.CurrentOffset];
1691 rc = TokenBuilder_BuildContext(SAParams_p, TokenContext_p);
1692 if (rc != TKB_STATUS_OK)
1693 {
1694 return SAB_ERROR;
1695 }
1696 }
1697#endif
1698
1699
1700 return SAB_STATUS_OK;
1701}
1702
1703
1704/*----------------------------------------------------------------------------
1705 * SABuilder_SetLargeTransformOffset();
1706 */
1707SABuilder_Status_t
1708SABuilder_SetLargeTransformOffset(
1709 unsigned int Offset)
1710{
1711#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_SSLTLS_EXTENDED)
1712 LargeTransformOffset = Offset;
1713 return SAB_STATUS_OK;
1714#else
1715 IDENTIFIER_NOT_USED(Offset);
1716 return SAB_UNSUPPORTED_FEATURE;
1717#endif
1718}
1719
1720/* end of file sa_builder.c */