1 /*--------------------------------------------------------------------------*/
2 /* Copyright 2020-2021 NXP                                                  */
3 /*                                                                          */
4 /* NXP Confidential. This software is owned or controlled by NXP and may    */
5 /* only be used strictly in accordance with the applicable license terms.   */
6 /* By expressly accepting such terms or by downloading, installing,         */
7 /* activating and/or otherwise using the software, you are agreeing that    */
8 /* you have read, and that you agree to comply with and are bound by, such  */
9 /* license terms. If you do not agree to be bound by the applicable license */
10 /* terms, then you may not retain, install, activate or otherwise use the   */
11 /* software.                                                                */
12 /*--------------------------------------------------------------------------*/
13 
14 /**
15  * @file  mcuxCsslFlowProtection.h
16  * @brief Provides the API for the CSSL flow protection mechanism.
17  */
18 
19 #ifndef MCUX_CSSL_FLOW_PROTECTION_H_
20 #define MCUX_CSSL_FLOW_PROTECTION_H_
21 
22 /* Include the actual implementation of the flow protection mechanism. */
23 #include <internal/mcuxCsslFlowProtection_Impl.h>
24 
25 /**
26  * @addtogroup mcuxCsslAPI MCUX CSSL -- API
27  *
28  * @defgroup mcuxCsslFlowProtection Flow Protection API
29  * @brief Flow protection mechanism.
30  * @ingroup mcuxCsslAPI
31  */
32 
33 
34 /**
35  * @defgroup csslFpCore Flow protection core functionality
36  * @brief Flow protection handling core functionality.
37  * @ingroup mcuxCsslFlowProtection
38  *
39  * @todo Extend this description of the core functionality which relies
40  *       basically on the function calling flow protection.
41  *
42  * @declaration{MCUX_CSSL_FP_FUNCTION_DECL}
43  * @event{MCUX_CSSL_FP_FUNCTION_CALL}
44  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED}
45  */
46 
47 /**
48  * @defgroup csslFpFunction Function calling flow protection
49  * @brief Support for flow protected functions.
50  * @ingroup mcuxCsslFlowProtection
51  *
52  * @declaration{MCUX_CSSL_FP_FUNCTION_DECL}
53  * @event{MCUX_CSSL_FP_FUNCTION_CALL}
54  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED}
55  */
56 
57 /**
58  * @def MCUX_CSSL_FP_PROTECTED_TYPE
59  * @brief Based on a given base type, builds a return type with flow
60  *        protection.
61  * @ingroup csslFpFunction
62  *
63  * This macro must be used to wrap the function return type. For example:
64  * @code
65  * MCUX_CSSL_FP_FUNCTION_DECL(someFunction)
66  * MCUX_CSSL_FP_PROTECTED_TYPE(uint32_t) someFunction(void);
67  * @endcode
68  *
69  * Note that depending on the selected flow protection mechanism, the width of
70  * the result type may be limited to 32 bits or less to allow encoding a
71  * protection token in the other half of a 64-bit return value.
72  *
73  * @see MCUX_CSSL_FP_FUNCTION_DEF
74  *
75  * @param resultType The type to be converted into a protected type.
76  */
77 #define MCUX_CSSL_FP_PROTECTED_TYPE(resultType) \
78   MCUX_CSSL_FP_PROTECTED_TYPE_IMPL(resultType)
79 
80 /**
81  * @def MCUX_CSSL_FP_COUNTER_STMT
82  * @brief A statement which is only evaluated if a secure counter is used.
83  * @api
84  * @ingroup csslFpFunction
85  *
86  * This macro can be used to create counting variables that are only present if
87  * the active configuration uses a secure counter, to avoid warnings about
88  * unused variables.
89  *
90  * @param statement The statement to be conditionally included.
91  */
92 #define MCUX_CSSL_FP_COUNTER_STMT(statement) \
93   MCUX_CSSL_FP_COUNTER_STMT_IMPL(statement)
94 
95 
96 /**
97  * @def MCUX_CSSL_FP_FUNCTION_DECL
98  * @brief Declaration of a flow protected function.
99  * @api
100  * @ingroup csslFpFunction
101  *
102  * This declaration must be placed just in front of the actual function
103  * declaration. For example:
104  * @code
105  * MCUX_CSSL_FP_FUNCTION_DECL(someFunction) // Note: no semicolon here
106  * uint32_t someFunction(void);
107  * @endcode
108  *
109  * @event{MCUX_CSSL_FP_FUNCTION_CALL}
110  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED}
111  *
112  * @see MCUX_CSSL_FP_FUNCTION_DEF
113  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
114  * @see MCUX_CSSL_FP_FUNCTION_EXIT
115  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
116  *
117  * @param id Identifier for the function that is flow protected.
118  */
119 #define MCUX_CSSL_FP_FUNCTION_DECL(id) \
120   MCUX_CSSL_FP_FUNCTION_DECL_IMPL(id)
121 
122 /**
123  * @def MCUX_CSSL_FP_FUNCTION_DEF
124  * @brief Definition of a flow protected function.
125  * @api
126  * @ingroup csslFpFunction
127  *
128  * This definition macro must be placed just in front of the actual function
129  * definition, that has been previously declared as flow protected using
130  * #MCUX_CSSL_FP_FUNCTION_DECL. For example:
131  * @code
132  * // someHeader.h
133  * MCUX_CSSL_FP_FUNCTION_DECL(someFunction) // Note: no semicolon here
134  * uint32_t someFunction(void);
135  *
136  * // someFile.c
137  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
138  * uint32_t someFunction(void)
139  * {
140  *   // some function body
141  * }
142  * @endcode
143  *
144  * @see MCUX_CSSL_FP_FUNCTION_DECL
145  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
146  * @see MCUX_CSSL_FP_FUNCTION_EXIT
147  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
148  *
149  * @param id Identifier for the function that is flow protected.
150  */
151 #define MCUX_CSSL_FP_FUNCTION_DEF(id) \
152   MCUX_CSSL_FP_FUNCTION_DEF_IMPL(id)
153 
154 /**
155  * @def MCUX_CSSL_FP_FUNCTION_ENTRY
156  * @brief Flow protection handler for the function entry point.
157  * @api
158  * @ingroup csslFpFunction
159  *
160  * This entry macro should be placed at the start of the function body that
161  * needs to be protected. The function must have been declared before as flow
162  * protected using #MCUX_CSSL_FP_FUNCTION_DECL. For example:
163  * @code
164  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
165  * uint32_t someFunction(void)
166  * {
167  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
168  *   // remainder of the function body
169  * }
170  * @endcode
171  *
172  * The only statements that should be placed before this one, are declarations
173  * for flow protected operations that are already used as expectations in this
174  * macro. For example:
175  * @code
176  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
177  * uint32_t someFunction(uint32_t count)
178  * {
179  *   MCUX_CSSL_FP_LOOP_DECL(someLoop);
180  *   MCUX_CSSL_FP_LOOP_DECL(otherLoop);
181  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction,
182  *     MCUX_CSSL_FP_LOOP_ITERATIONS(someLoop, count),
183  *     MCUX_CSSL_FP_LOOP_ITERATIONS(otherLoop, 2u * count)
184  *   );
185  *   // Remainder of the function body, where someLoop makes count iterations,
186  *   // and otherLoop 2*count iterations.
187  * }
188  * @endcode
189  *
190  * @see MCUX_CSSL_FP_FUNCTION_DECL
191  * @see MCUX_CSSL_FP_FUNCTION_DEF
192  * @see MCUX_CSSL_FP_FUNCTION_EXIT
193  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
194  *
195  * @param ...    The following parameters need to be passed (comma separated):
196  *        - id:     Identifier of the function that has just been entered. <br>
197  *        - expect: Zero or more (comma separated) declarations of expected code
198  *               flow behavior.
199  */
200 #define MCUX_CSSL_FP_FUNCTION_ENTRY(...) \
201   MCUX_CSSL_FP_FUNCTION_ENTRY_IMPL(__VA_ARGS__)
202 
203 /**
204  * @def MCUX_CSSL_FP_FUNCTION_EXIT
205  * @brief Flow protection handler for the function exit point.
206  * @api
207  * @ingroup csslFpFunction
208  *
209  * This exit macro must replace the regular \c return statements of a protected
210  * function. Given the following unprotected example:
211  * @code
212  * uint32_t someFunction(void)
213  * {
214  *   // some function body
215  *   return 0;
216  * }
217  * @endcode
218  * The protected version would become:
219  * @code
220  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
221  * uint32_t someFunction(void)
222  * {
223  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
224  *   // remainder of the function body
225  *   MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0);
226  * }
227  * @endcode
228  *
229  * @see MCUX_CSSL_FP_FUNCTION_DECL
230  * @see MCUX_CSSL_FP_FUNCTION_DEF
231  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
232  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
233  *
234  * @param ...    The following parameters need to be passed (comma separated):
235  *        - id:     Identifier of the function from which we will exit.
236  *        - result: Result that should be encoded in the return value.
237  *        - expect: Zero or more (comma separated) declarations of expected code
238  *               flow behavior.
239  * @return       A value in which both \p result and a flow protection token
240  *               are encoded.
241  */
242 #define MCUX_CSSL_FP_FUNCTION_EXIT(...) \
243   MCUX_CSSL_FP_FUNCTION_EXIT_IMPL(__VA_ARGS__)
244 
245 /**
246  * @def MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
247  * @brief Flow protection handler for the function exit point which includes
248  *        an actual check of the code flow.
249  * @api
250  * @ingroup csslFpFunction
251  *
252  * This exit macro must replace the regular \c return statements of a protected
253  * function. In addition to #MCUX_CSSL_FP_FUNCTION_EXIT it also checks the flow
254  * protection, and selects the return value accordingly. For example:
255  * @code
256  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
257  * uint32_t someFunction(void)
258  * {
259  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
260  *   // remainder of the function body
261  *   MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK(someFunction, 0, 0xFAu);
262  * }
263  * @endcode
264  *
265  * @see MCUX_CSSL_FP_FUNCTION_DECL
266  * @see MCUX_CSSL_FP_FUNCTION_DEF
267  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
268  * @see MCUX_CSSL_FP_FUNCTION_EXIT
269  *
270  * @param ...    The following parameters need to be passed (comma separated):
271  *        - id:      Identifier of the function from which we will exit.
272  *        - pass:    Result that should be encoded in the return value if the flow
273  *                   protection check passed.
274  *        - fail:    Result that should be encoded in the return value if the flow
275  *                   protection check failed.
276  *        - expect:  Zero or more (comma separated) declarations of expected code
277  *                  flow behavior.
278  * @return       A value in which both the result (either \p pass or \p fail)
279  *               and a flow protection token are encoded.
280  */
281 #define MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK(...) \
282   MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK_IMPL(__VA_ARGS__)
283 
284 /**
285  * @def MCUX_CSSL_FP_FUNCTION_EXIT_VOID
286  * @brief Flow protection handler for the exit point of functions with the
287  *        return type \c void.
288  * @api
289  * @ingroup csslFpFunction
290  *
291  * This exit macro must replace the regular \c return statements of a protected
292  * void function. Given the following unprotected example:
293  * @code
294  * void someFunction(void)
295  * {
296  *   // some function body
297  *   return 0;
298  * }
299  * @endcode
300  * The protected version would become:
301  * @code
302  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
303  * void someFunction(void)
304  * {
305  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
306  *   // remainder of the function body
307  *   MCUX_CSSL_FP_FUNCTION_EXIT_VOID(someFunction);
308  * }
309  * @endcode
310  *
311  * @see MCUX_CSSL_FP_FUNCTION_DECL
312  * @see MCUX_CSSL_FP_FUNCTION_DEF
313  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
314  *
315  * @param ...       The following parameters need to be passed (comma separated):
316  *        - id:     Identifier of the function from which we will exit.
317  *        - expect: Zero or more (comma separated) declarations of expected code
318  *                  flow behavior.
319  * @return       A protected return value of type void.
320  */
321 #define MCUX_CSSL_FP_FUNCTION_EXIT_VOID(...) \
322   MCUX_CSSL_FP_FUNCTION_EXIT_VOID_IMPL(__VA_ARGS__)
323 
324 /**
325  * @def MCUX_CSSL_FP_RESULT
326  * @brief Extract the result value from a protected \p return value.
327  * @ingroup csslFpFunction
328  *
329  * @param return The protected return value which contains the result.
330  */
331 #define MCUX_CSSL_FP_RESULT(return) \
332   MCUX_CSSL_FP_RESULT_IMPL(return)
333 
334 /**
335  * @def MCUX_CSSL_FP_PROTECTION_TOKEN
336  * @brief Extract the protection token value from a protected \p return value.
337  * @ingroup csslFpFunction
338  *
339  * Note that this macro is only used with a local security counter,
340  * e.g. for configuration CSSL_SC_USE_SW_LOCAL
341  *
342  * @param return The protected return value which contains the protection token.
343  */
344 #define MCUX_CSSL_FP_PROTECTION_TOKEN(return) \
345   MCUX_CSSL_FP_PROTECTION_TOKEN_IMPL(return)
346 
347 /**
348  * @def MCUX_CSSL_FP_FUNCTION_CALL
349  * @brief Call a flow protected function.
350  * @api
351  * @ingroup csslFpFunction
352  *
353  * This function call macro encapsulates the flow protection handling needed
354  * for calling a function. In particular it takes care of extracting the flow
355  * protection token from the return value (which has been inserted by
356  * #MCUX_CSSL_FP_FUNCTION_EXIT or #MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK) and
357  * incorporating that in the flow protection of the current function. For
358  * example:
359  * @code
360  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
361  * uint32_t someFunction(void)
362  * {
363  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
364  *   // ...
365  *   MCUX_CSSL_FP_FUNCTION_CALL(result, otherFunction());
366  *   // ...
367  *   MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
368  *     MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction)
369  *   );
370  * }
371  * @endcode
372  *
373  * For functions returning void, the macro #MCUX_CSSL_FP_FUNCTION_CALL_VOID
374  * exists.
375  *
376  * @declaration{MCUX_CSSL_FP_FUNCTION_DECL}
377  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED}
378  *
379  * @param ...    The following parameters need to be passed (comma separated):
380  *        - result: Fresh variable name to store the result of \p call.
381  *        - call:   The (protected) function call that must be performed.
382  */
383 #define MCUX_CSSL_FP_FUNCTION_CALL(...) \
384   MCUX_CSSL_FP_FUNCTION_CALL_IMPL(__VA_ARGS__)
385 
386 /**
387  * @def MCUX_CSSL_FP_FUNCTION_CALL_VOID
388  * @brief Call a flow protected void function.
389  * @api
390  * @ingroup csslFpFunction
391  *
392  * This function call macro encapsulates the flow protection handling needed
393  * for calling a void function. In particular it takes care of extracting the
394  * flow protection token from the return value (which has been inserted by
395  * #MCUX_CSSL_FP_FUNCTION_EXIT or #MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK) and
396  * incorporating that in the flow protection of the current function. For
397  * example:
398  * @code
399  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
400  * uint32_t someFunction(void)
401  * {
402  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
403  *   // ...
404  *   MCUX_CSSL_FP_FUNCTION_CALL_VOID(otherFunction());
405  *   // ...
406  *   MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
407  *     MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction)
408  *   );
409  * }
410  * @endcode
411  *
412  * @declaration{MCUX_CSSL_FP_FUNCTION_DECL}
413  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED}
414  *
415  * @param ...    The following parameters need to be passed (comma separated):
416  *        - call:   The (protected) void function call that must be performed.
417  */
418 #define MCUX_CSSL_FP_FUNCTION_CALL_VOID(...) \
419   MCUX_CSSL_FP_FUNCTION_CALL_VOID_IMPL(__VA_ARGS__)
420 
421 /**
422  * @def MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED
423  * @brief Call a flow protected function from unprotected code.
424  * @api
425  * @ingroup csslFpFunction
426  *
427  * This function call macro encapsulates the flow protection handling needed
428  * for calling a function from within a function which does not have local
429  * flow protection, or which uses a different flow protection mechanism than
430  * the one provided by CSSL. In particular it takes care of extracting the
431  * protection token and result from the return value (which has been inserted
432  * by #MCUX_CSSL_FP_FUNCTION_EXIT or #MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK).
433  * For example:
434  * @code
435  * uint32_t someUnprotectedFunction(void)
436  * {
437  *   // ...
438  *   MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED(
439  *     result,
440  *     token,
441  *     otherFunction());
442  *   // Check the protection token
443  *   if(MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction) != token)
444  *   {
445  *     return FAULT;
446  *   }
447  *   // ... The following code may use 'result' as a variable ...
448  * }
449  * @endcode
450  *
451  * @param ...    The following parameters need to be passed (comma separated):
452  *        - result: Fresh variable name to store the result of \p call.
453  *        - token:  Fresh variable name to store the protection token of \p call.
454  *        - call:   The (protected) function call that must be performed.
455  */
456 #define MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED(...) \
457   MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED_IMPL(__VA_ARGS__)
458 
459   /**
460  * @def MCUX_CSSL_FP_FUNCTION_CALL_VOID_PROTECTED
461  * @brief Call a flow protected void function from unprotected code.
462  * @api
463  * @ingroup csslFpFunction
464  *
465  * This function call macro encapsulates the flow protection handling needed
466  * for calling a void function from within a function which does not have flow
467  * protection, or which uses a different flow protection mechanism than the one
468  * provided by CSSL. In particular it takes care of extracting the protection
469  * token and result from the return value (which has been inserted by
470  * #MCUX_CSSL_FP_FUNCTION_EXIT or #MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK).
471  * For example:
472  * @code
473  * uint32_t someUnprotectedFunction(void)
474  * {
475  *   // ...
476  *   MCUX_CSSL_FP_FUNCTION_CALL_PROTECTED(
477  *     token,
478  *     protectedVoidFunction());
479  *   // Check the protection token
480  *   if(MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction) != token)
481  *   {
482  *     return FAULT;
483  *   }
484  *   // ...
485  * }
486  * @endcode
487  *
488  * @param ...    The following parameters need to be passed (comma separated):
489  *        - token:  Fresh variable name to store the protection token of \p call.
490  *        - call:   The (protected) function call that must be performed.
491  */
492 #define MCUX_CSSL_FP_FUNCTION_CALL_VOID_PROTECTED(...) \
493   MCUX_CSSL_FP_FUNCTION_CALL_VOID_PROTECTED_IMPL(__VA_ARGS__)
494 
495 /**
496  * @def MCUX_CSSL_FP_FUNCTION_CALL_BEGIN
497  * @brief Call a flow protected function and check the protection token.
498  * @api
499  * @ingroup csslFpFunction
500  *
501  * This function call macro encapsulates the flow protection handling needed
502  * for calling a function from within a function which does not have local
503  * flow protection, or which uses a different flow protection mechanism than
504  * the one provided by CSSL. In particular it takes care of extracting the
505  * protection token and result from the return value (which has been inserted
506  * by #MCUX_CSSL_FP_FUNCTION_EXIT or #MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK).
507  * For example:
508  * @code
509  * uint32_t someUnprotectedFunction(void)
510  * {
511  *   // ...
512  *   MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(
513  *     result,
514  *     token,
515  *     otherFunction());
516  *   // Check the protection token
517  *   if(MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction) != token)
518  *   {
519  *     return FAULT;
520  *   }
521  *   // ... The following code may use 'result' as a variable ...
522  *   MCUX_CSSL_FP_FUNCTION_CALL_END();
523  *   // ... result is invalid here ...
524  * }
525  * @endcode
526  *
527  * @param ...    The following parameters need to be passed (comma separated):
528  *        - result: Fresh variable name to store the result of \p call.
529  *        - token:  Fresh variable name to store the protection token of \p call.
530  *        - call:   The (protected) function call that must be performed.
531  */
532 #define MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(...) \
533   MCUX_CSSL_FP_FUNCTION_CALL_BEGIN_IMPL(__VA_ARGS__)
534 
535 /**
536  * @def MCUX_CSSL_FP_FUNCTION_CALL_END
537  * @brief End a function call section started by
538  * #MCUX_CSSL_FP_FUNCTION_CALL_BEGIN.
539  * @api
540  * @ingroup csslFpFunction
541  *
542  * Example:
543  * @code
544  * uint32_t someUnprotectedFunction(void)
545  * {
546  *   // ...
547  *   MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(
548  *     result,
549  *     token,
550  *     otherFunction());
551  *   // Check the protection token
552  *   if(MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction) != token)
553  *   {
554  *     return FAULT;
555  *   }
556  *   // ... The following code may use 'result' as a variable ...
557  *   MCUX_CSSL_FP_FUNCTION_CALL_END();
558  *   // ... result is invalid here ...
559  * }
560  * @endcode
561  *
562  * @param ...    The following parameters need to be passed (comma separated):
563  *        - result: Fresh variable name to store the result of \p call.
564  *        - token:  Fresh variable name to store the protection token of \p call.
565  *        - call:   The (protected) function call that must be performed.
566  */
567 #define MCUX_CSSL_FP_FUNCTION_CALL_END(...) \
568   MCUX_CSSL_FP_FUNCTION_CALL_END_IMPL(__VA_ARGS__)
569 
570 /**
571  * @def MCUX_CSSL_FP_FUNCTION_CALLED
572  * @brief Expectation of a called function.
573  * @api
574  * @ingroup csslFpFunction
575  *
576  * This expectation macro indicates to the flow protection mechanism that a
577  * function call is expected to happen (if placed before the actual call), for
578  * example:
579  * @code
580  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
581  * uint32_t someFunction(void)
582  * {
583  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction,
584  *     MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction)
585  *   );
586  *   // ...
587  *   MCUX_CSSL_FP_FUNCTION_CALL(result, otherFunction());
588  *   // ...
589  *   MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0);
590  * }
591  * @endcode
592  * Or that a function call has happened (if placed after the actual call), for
593  * example:
594  * @code
595  * MCUX_CSSL_FP_FUNCTION_DEF(someFunction) // Note: no semicolon here
596  * uint32_t someFunction(void)
597  * {
598  *   MCUX_CSSL_FP_FUNCTION_ENTRY(someFunction);
599  *   // ...
600  *   MCUX_CSSL_FP_FUNCTION_CALL(result, otherFunction());
601  *   // ...
602  *   MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
603  *     MCUX_CSSL_FP_FUNCTION_CALLED(otherFunction)
604  *   );
605  * }
606  * @endcode
607  *
608  * @declaration{MCUX_CSSL_FP_FUNCTION_DECL}
609  * @event{MCUX_CSSL_FP_FUNCTION_CALL}
610  *
611  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
612  * @see MCUX_CSSL_FP_FUNCTION_EXIT
613  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
614  * @see MCUX_CSSL_FP_EXPECT
615  *
616  * @param ...    The following parameters need to be passed (comma separated):
617  *        -id: Identifier of the function that is expected to be called.
618  */
619 #define MCUX_CSSL_FP_FUNCTION_CALLED(...) \
620   MCUX_CSSL_FP_FUNCTION_CALLED_IMPL(__VA_ARGS__)
621 
622 
623 
624 /**
625  * @defgroup csslFpLoop Looping flow protection
626  * @brief Support for flow protected loops.
627  * @ingroup mcuxCsslFlowProtection
628  *
629  * @declaration{MCUX_CSSL_FP_LOOP_DECL}
630  * @event{MCUX_CSSL_FP_LOOP_ITERATION}
631  * @expectation{MCUX_CSSL_FP_LOOP_ITERATIONS}
632  */
633 
634 /**
635  * @def MCUX_CSSL_FP_LOOP_DECL
636  * @brief Declaration of a flow protected loop.
637  * @api
638  * @ingroup csslFpLoop
639  *
640  * To inform the flow protection mechanism about a loop that needs to be
641  * protected, a loop identifier needs to be declared. This identifier can then
642  * be used in the event and expectation macros. For example:
643  * @code
644  * MCUX_CSSL_FP_LOOP_DECL(someLoopIdentifier);
645  * for (uint32_t i = 0; i < 8; ++i)
646  * {
647  *   MCUX_CSSL_FP_LOOP_ITERATION(someLoopIdentifier);
648  * }
649  * // ...
650  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
651  *   MCUX_CSSL_FP_LOOP_ITERATIONS(someLoopIdentifier, 8)
652  * );
653  * @endcode
654  *
655  * @event{MCUX_CSSL_FP_LOOP_ITERATION}
656  * @expectation{MCUX_CSSL_FP_LOOP_ITERATIONS}
657  *
658  * @param id Identifier for the loop that is flow protected.
659  */
660 #define MCUX_CSSL_FP_LOOP_DECL(id) \
661   MCUX_CSSL_FP_LOOP_DECL_IMPL(id)
662 
663 /**
664  * @def MCUX_CSSL_FP_LOOP_ITERATION
665  * @brief Perform a loop iteration.
666  * @api
667  * @ingroup csslFpLoop
668  *
669  * This loop iteration macro informs the flow mechanism that an iteration event
670  * is performed for the loop declared by #MCUX_CSSL_FP_LOOP_DECL with the given
671  * \p id. For example:
672  * @code
673  * MCUX_CSSL_FP_LOOP_DECL(someLoopIdentifier);
674  * for (uint32_t i = 0; i < 8; ++i)
675  * {
676  *   MCUX_CSSL_FP_LOOP_ITERATION(someLoopIdentifier);
677  * }
678  * @endcode
679  *
680  * @declaration{MCUX_CSSL_FP_LOOP_DECL}
681  * @expectation{MCUX_CSSL_FP_LOOP_ITERATIONS}
682  *
683  * @param ...    The following parameters need to be passed (comma separated):
684  *        - id:      Identifier for the loop that is flow protected.
685  *        - expect:  Zero or more (comma separated) declarations of expected code
686  *                   flow behavior related to this event.
687  */
688 #define MCUX_CSSL_FP_LOOP_ITERATION(...) \
689   MCUX_CSSL_FP_LOOP_ITERATION_IMPL(__VA_ARGS__)
690 
691 /**
692  * @def MCUX_CSSL_FP_LOOP_ITERATIONS
693  * @brief Expected number of loop iterations.
694  * @api
695  * @ingroup csslFpLoop
696  *
697  * This expectation macro indicates to the flow protection mechanism that the
698  * loop declared by #MCUX_CSSL_FP_LOOP_DECL with the given \p id has made
699  * \p count iterations. For example:
700  * @code
701  * MCUX_CSSL_FP_LOOP_DECL(someLoopIdentifier);
702  * for (uint32_t i = 0; i < 8; ++i)
703  * {
704  *   MCUX_CSSL_FP_LOOP_ITERATION(someLoopIdentifier);
705  * }
706  * // ...
707  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
708  *   MCUX_CSSL_FP_LOOP_ITERATIONS(someLoopIdentifier, 8)
709  * );
710  * @endcode
711  *
712  * @declaration{MCUX_CSSL_FP_LOOP_DECL}
713  * @event{MCUX_CSSL_FP_LOOP_ITERATION}
714  *
715  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
716  * @see MCUX_CSSL_FP_FUNCTION_EXIT
717  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
718  * @see MCUX_CSSL_FP_EXPECT
719  *
720  * @param id    Identifier of the flow protected loop.
721  * @param count Number of expected iterations.
722  */
723 #define MCUX_CSSL_FP_LOOP_ITERATIONS(id, count) \
724   MCUX_CSSL_FP_LOOP_ITERATIONS_IMPL(id, count)
725 
726 
727 
728 /**
729  * @defgroup csslFpBranch Branching flow protection
730  * @brief Support for flow protected branches.
731  * @ingroup mcuxCsslFlowProtection
732  *
733  * @declaration{MCUX_CSSL_FP_BRANCH_DECL}
734  * @event{MCUX_CSSL_FP_BRANCH_POSITIVE,MCUX_CSSL_FP_BRANCH_NEGATIVE}
735  * @expectation{MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE,MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE}
736  */
737 
738 /**
739  * @def MCUX_CSSL_FP_BRANCH_DECL
740  * @brief Declaration of a flow protected branch.
741  * @api
742  * @ingroup csslFpBranch
743  *
744  * To inform the flow protection mechanism about a branch that needs to be
745  * protected, a branch identifier needs to be declared. This identifier can
746  * then be used in the events and expectation macros. For example:
747  * @code
748  * MCUX_CSSL_FP_BRANCH_DECL(someBranchIdentifier);
749  * if (condition)
750  * {
751  *   MCUX_CSSL_FP_BRANCH_POSITIVE(someBranchIdentifier);
752  * }
753  * else
754  * {
755  *   MCUX_CSSL_FP_BRANCH_NEGATIVE(someBranchIdentifier);
756  * }
757  * // ...
758  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
759  *   MCUX_CSSL_FP_BRANCH_TAKEN(someBranchIdentifier,
760  *     MCUX_CSSL_FP_BRANCH_POSITIVE_SCENARIO, condition)
761  * );
762  * @endcode
763  *
764  * @event{MCUX_CSSL_FP_BRANCH_POSITIVE,MCUX_CSSL_FP_BRANCH_NEGATIVE}
765  * @expectation{MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE,MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE}
766  *
767  * @param id Identifier for the branch that is flow protected.
768  */
769 #define MCUX_CSSL_FP_BRANCH_DECL(id) \
770   MCUX_CSSL_FP_BRANCH_DECL_IMPL(id)
771 
772 /**
773  * @def MCUX_CSSL_FP_BRANCH_POSITIVE
774  * @brief Positive scenario for a branch is executed.
775  * @api
776  * @ingroup csslFpBranch
777  *
778  * This branch event macro informs the flow mechanism that the positive scenario
779  * of the branch is executed for the branch declared by
780  * #MCUX_CSSL_FP_BRANCH_DECL with the given \p id. For example:
781  * @code
782  * MCUX_CSSL_FP_BRANCH_DECL(someBranchIdentifier);
783  * if (condition)
784  * {
785  *   MCUX_CSSL_FP_BRANCH_POSITIVE(someBranchIdentifier);
786  * }
787  * else
788  * {
789  *   MCUX_CSSL_FP_BRANCH_NEGATIVE(someBranchIdentifier);
790  * }
791  * // ...
792  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
793  *   MCUX_CSSL_FP_CONDITIONAL_IMPL(!condition,
794  *     MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE(someBranchIdentifier)
795  *   )
796  * );
797  * @endcode
798  *
799  * @declaration{MCUX_CSSL_FP_BRANCH_DECL}
800  * @expectation{MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE}
801  *
802  * @param ...    The following parameters need to be passed (comma separated):
803  *        - id:     Identifier for the branch for which the positive scenario is
804  *                  executed.
805  *        - expect: Zero or more (comma separated) declarations of expected code
806  *                  flow behavior related to this event.
807  */
808 #define MCUX_CSSL_FP_BRANCH_POSITIVE(...) \
809   MCUX_CSSL_FP_BRANCH_POSITIVE_IMPL(__VA_ARGS__)
810 
811 /**
812  * @def MCUX_CSSL_FP_BRANCH_NEGATIVE
813  * @brief Negative scenario of a branch is executed.
814  * @api
815  * @ingroup csslFpBranch
816  *
817  * This branch event macro informs the flow mechanism that the positive scenario
818  * of the branch is executed for the branch declared by
819  * #MCUX_CSSL_FP_BRANCH_DECL with the given \p id. For example:
820  * @code
821  * MCUX_CSSL_FP_BRANCH_DECL(someBranchIdentifier);
822  * if (condition)
823  * {
824  *   MCUX_CSSL_FP_BRANCH_POSITIVE(someBranchIdentifier);
825  * }
826  * else
827  * {
828  *   MCUX_CSSL_FP_BRANCH_NEGATIVE(someBranchIdentifier);
829  * }
830  * // ...
831  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
832  *   MCUX_CSSL_FP_CONDITIONAL_IMPL(!condition,
833  *     MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE(someBranchIdentifier)
834  *   )
835  * );
836  * @endcode
837  *
838  * @declaration{MCUX_CSSL_FP_BRANCH_DECL}
839  * @expectation{MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE}
840  *
841  * @param ...    The following parameters need to be passed (comma separated):
842  *        - id:     Identifier for the branch for which the negative scenario is
843  *                  executed.
844  *        - expect: Zero or more (comma separated) declarations of expected code
845  *                  flow behavior related to this event.
846  */
847 #define MCUX_CSSL_FP_BRANCH_NEGATIVE(...) \
848   MCUX_CSSL_FP_BRANCH_NEGATIVE_IMPL(__VA_ARGS__)
849 
850 /**
851  * @def MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE
852  * @brief Expectation that positive branch has been taken.
853  * @api
854  * @ingroup csslFpBranch
855  *
856  * This expectation macro indicates to the flow protection mechanism that the
857  * branch declared by #MCUX_CSSL_FP_BRANCH_DECL with the given \p id has
858  * executed the positive scenario (under the given \p condition). For example:
859  * @code
860  * MCUX_CSSL_FP_BRANCH_DECL(someBranchIdentifier);
861  * if (condition)
862  * {
863  *   MCUX_CSSL_FP_BRANCH_POSITIVE(someBranchIdentifier);
864  * }
865  * else
866  * {
867  *   MCUX_CSSL_FP_BRANCH_NEGATIVE(someBranchIdentifier);
868  * }
869  * // ...
870  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
871  *   // Providing the condition as part of the branch expectation.
872  *   // Alternatively, the expectation can be placed in a conditional block.
873  *   MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE(someBranchIdentifier, condition)
874  * );
875  * @endcode
876  *
877  * @declaration{MCUX_CSSL_FP_BRANCH_DECL}
878  * @event{MCUX_CSSL_FP_BRANCH_POSITIVE}
879  *
880  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
881  * @see MCUX_CSSL_FP_FUNCTION_EXIT
882  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
883  * @see MCUX_CSSL_FP_EXPECT
884  * @see MCUX_CSSL_FP_CONDITIONAL
885  *
886  * @param ...    The following parameters need to be passed (comma separated):
887  *        - id:        Identifier of the flow protected branch.
888  *        - condition: Optional, condition under which this branch is taken.
889  */
890 #define MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE(...) \
891   MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE_IMPL(__VA_ARGS__)
892 
893 /**
894  * @def MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE
895  * @brief Expectation that negative branch has been taken.
896  * @api
897  * @ingroup csslFpBranch
898  *
899  * This expectation macro indicates to the flow protection mechanism that the
900  * branch declared by #MCUX_CSSL_FP_BRANCH_DECL with the given \p id has
901  * executed the negative scenario (under the given \p condition). For example:
902  * @code
903  * MCUX_CSSL_FP_BRANCH_DECL(someBranchIdentifier);
904  * if (condition)
905  * {
906  *   MCUX_CSSL_FP_BRANCH_POSITIVE(someBranchIdentifier);
907  * }
908  * else
909  * {
910  *   MCUX_CSSL_FP_BRANCH_NEGATIVE(someBranchIdentifier);
911  * }
912  * // ...
913  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, 0,
914  *   // Providing the branch expectation as part of a conditional block.
915  *   // Alternatively, the condition can be provided in the branch expectation.
916  *   MCUX_CSSL_FP_CONDITIONAL(!condition,
917  *     MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE(someBranchIdentifier)
918  *   )
919  * );
920  * @endcode
921  *
922  * @declaration{MCUX_CSSL_FP_BRANCH_DECL}
923  * @event{MCUX_CSSL_FP_BRANCH_NEGATIVE}
924  *
925  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
926  * @see MCUX_CSSL_FP_FUNCTION_EXIT
927  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
928  * @see MCUX_CSSL_FP_EXPECT
929  * @see MCUX_CSSL_FP_CONDITIONAL
930  *
931  * @param ...    The following parameters need to be passed (comma separated):
932  *        - id:        Identifier of the flow protected branch.
933  *        - condition: Optional, condition under which this branch is taken.
934  */
935 #define MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE(...) \
936   MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE_IMPL(__VA_ARGS__)
937 
938 
939 
940 /**
941  * @defgroup csslFpSwitch Switching flow protection
942  * @brief Support for flow protected switches.
943  * @ingroup mcuxCsslFlowProtection
944  *
945  * @declaration{MCUX_CSSL_FP_SWITCH_DECL}
946  * @event{MCUX_CSSL_FP_SWITCH_CASE,MCUX_CSSL_FP_SWITCH_DEFAULT}
947  * @expectation{MCUX_CSSL_FP_SWITCH_TAKEN,MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT}
948  */
949 
950 /**
951  * @def MCUX_CSSL_FP_SWITCH_DECL
952  * @brief Declaration of a flow protected switch.
953  * @api
954  * @ingroup csslFpSwitch
955  *
956  * To inform the flow protection mechanism about a switch that needs to be
957  * protected, a switch identifier needs to be declared. This identifier can
958  * then be used in the events and expectation macros. For example:
959  * @code
960  * MCUX_CSSL_FP_SWITCH_DECL(someSwitchIdentifier);
961  * switch (arg)
962  * {
963  *   case 0xC0DEu:
964  *   {
965  *     result = 0xC0DEu;
966  *     MCUX_CSSL_FP_SWITCH_CASE(someSwitchIdentifier, 0xC0DEu);
967  *     break;
968  *   }
969  *   default:
970  *   {
971  *     result = 0;
972  *     MCUX_CSSL_FP_SWITCH_DEFAULT(someSwitchIdentifier);
973  *     break;
974  *   }
975  * }
976  * // ...
977  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, result,
978  *   // Option 1: provide the condition as part of the switch expectation.
979  *   MCUX_CSSL_FP_SWITCH_TAKEN(someSwitchIdentifier, 0xC0DEu, 0xC0DEu == arg),
980  *   // Option 2: place the switch expectation in a conditional block.
981  *   MCUX_CSSL_FP_CONDITIONAL(0xC0DEu != arg),
982  *     MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT(someSwitchIdentifier)
983  *   )
984  * );
985  * @endcode
986  *
987  * @event{MCUX_CSSL_FP_SWITCH_CASE,MCUX_CSSL_FP_SWITCH_DEFAULT}
988  * @expectation{MCUX_CSSL_FP_SWITCH_TAKEN,MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT}
989  *
990  * @param id Identifier for the switch that is flow protected.
991  */
992 #define MCUX_CSSL_FP_SWITCH_DECL(id) \
993   MCUX_CSSL_FP_SWITCH_DECL_IMPL(id)
994 
995 /**
996  * @def MCUX_CSSL_FP_SWITCH_CASE
997  * @brief Case that is being handled from a switch.
998  * @api
999  * @ingroup csslFpSwitch
1000  *
1001  * This switch event macro informs the flow mechanism that the given \p case of
1002  * the switch is executed for the switch declared by #MCUX_CSSL_FP_SWITCH_DECL
1003  * with the given \p id. For example:
1004  * @code
1005  * MCUX_CSSL_FP_SWITCH_DECL(someSwitchIdentifier);
1006  * switch (arg)
1007  * {
1008  *   case 0xC0DEu:
1009  *   {
1010  *     result = 0xC0DEu;
1011  *     MCUX_CSSL_FP_SWITCH_CASE(someSwitchIdentifier, 0xC0DEu);
1012  *     break;
1013  *   }
1014  *   default:
1015  *   {
1016  *     result = 0;
1017  *     MCUX_CSSL_FP_SWITCH_DEFAULT(someSwitchIdentifier);
1018  *     break;
1019  *   }
1020  * }
1021  * // ...
1022  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, result,
1023  *   // Option 1: provide the condition as part of the switch expectation.
1024  *   MCUX_CSSL_FP_SWITCH_TAKEN(someSwitchIdentifier, 0xC0DEu, 0xC0DEu == arg),
1025  *   // Option 2: place the switch expectation in a conditional block.
1026  *   MCUX_CSSL_FP_CONDITIONAL(0xC0DEu != arg),
1027  *     MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT(someSwitchIdentifier)
1028  *   )
1029  * );
1030  * @endcode
1031  *
1032  * @declaration{MCUX_CSSL_FP_SWITCH_DECL}
1033  * @expectation{MCUX_CSSL_FP_SWITCH_TAKEN}
1034  *
1035  * @param ...    The following parameters need to be passed (comma separated):
1036  *        - id:     Identifier of the flow protected switch.
1037  *        - case:   Case value that is chosen in the switch.
1038  *        - expect: Zero or more (comma separated) declarations of expected code
1039  *                  flow behavior related to this event.
1040  */
1041 #define MCUX_CSSL_FP_SWITCH_CASE(...) \
1042   MCUX_CSSL_FP_SWITCH_CASE_IMPL(__VA_ARGS__)
1043 
1044 /**
1045  * @def MCUX_CSSL_FP_SWITCH_DEFAULT
1046  * @brief Case that is being handled from a switch.
1047  * @api
1048  * @ingroup csslFpSwitch
1049  *
1050  * This switch event macro informs the flow mechanism that the default case of
1051  * the switch is executed for the switch declared by #MCUX_CSSL_FP_SWITCH_DECL
1052  * with the given \p id. For example:
1053  * @code
1054  * MCUX_CSSL_FP_SWITCH_DECL(someSwitchIdentifier);
1055  * switch (arg)
1056  * {
1057  *   case 0xC0DEu:
1058  *   {
1059  *     result = 0xC0DEu;
1060  *     MCUX_CSSL_FP_SWITCH_CASE(someSwitchIdentifier, 0xC0DEu);
1061  *     break;
1062  *   }
1063  *   default:
1064  *   {
1065  *     result = 0;
1066  *     MCUX_CSSL_FP_SWITCH_DEFAULT(someSwitchIdentifier);
1067  *     break;
1068  *   }
1069  * }
1070  *
1071  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, result,
1072  *   // Option 1: provide the condition as part of the switch expectation.
1073  *   MCUX_CSSL_FP_SWITCH_TAKEN(argCheck, 0xC0DEu, 0xC0DEu == arg),
1074  *   // Option 2: place the switch expectation in a conditional block.
1075  *   MCUX_CSSL_FP_CONDITIONAL(0xC0DEu != arg),
1076  *     MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT(someSwitchIdentifier)
1077  *   )
1078  * );
1079  * @endcode
1080  *
1081  * @declaration{MCUX_CSSL_FP_SWITCH_DECL}
1082  * @expectation{MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT}
1083  *
1084  * @param ...    The following parameters need to be passed (comma separated):
1085  *        - id:     Identifier of the flow protected switch.
1086  *        - expect: Zero or more (comma separated) declarations of expected code
1087  *                  flow behavior related to this event.
1088  */
1089 #define MCUX_CSSL_FP_SWITCH_DEFAULT(...) \
1090   MCUX_CSSL_FP_SWITCH_DEFAULT_IMPL(__VA_ARGS__)
1091 
1092 /**
1093  * @def MCUX_CSSL_FP_SWITCH_TAKEN
1094  * @brief Expected that a specific case is handled from a switch.
1095  * @api
1096  * @ingroup csslFpSwitch
1097  *
1098  * This expectation macro indicates to the flow protection mechanism that the
1099  * switch declared by #MCUX_CSSL_FP_SWITCH_DECL with the given \p id has
1100  * executed the \p case (under the given \p condition). For example:
1101  * @code
1102  * MCUX_CSSL_FP_SWITCH_DECL(someSwitchIdentifier);
1103  * switch (arg)
1104  * {
1105  *   case 0xC0DEu:
1106  *   {
1107  *     result = 0xC0DEu;
1108  *     MCUX_CSSL_FP_SWITCH_CASE(someSwitchIdentifier, 0xC0DEu);
1109  *     break;
1110  *   }
1111  *   default:
1112  *   {
1113  *     result = 0;
1114  *     MCUX_CSSL_FP_SWITCH_DEFAULT(someSwitchIdentifier);
1115  *     break;
1116  *   }
1117  * }
1118  *
1119  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, result,
1120  *   // Option 1: provide the condition as part of the switch expectation.
1121  *   MCUX_CSSL_FP_SWITCH_TAKEN(argCheck, 0xC0DEu, 0xC0DEu == arg),
1122  *   // Option 2: place the switch expectation in a conditional block.
1123  *   MCUX_CSSL_FP_CONDITIONAL(0xC0DEu != arg),
1124  *     MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT(someSwitchIdentifier)
1125  *   )
1126  * );
1127  * @endcode
1128  *
1129  * @declaration{MCUX_CSSL_FP_SWITCH_DECL}
1130  * @event{MCUX_CSSL_FP_SWITCH_CASE}
1131  *
1132  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
1133  * @see MCUX_CSSL_FP_FUNCTION_EXIT
1134  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
1135  * @see MCUX_CSSL_FP_EXPECT
1136  *
1137  * @param ...    The following parameters need to be passed (comma separated):
1138  *        - id:        Identifier of the flow protected switch.
1139  *        - case:      Value of the case that is expected to be chosen in the
1140  *                     switch.
1141  *        - condition: Optional, condition under which the \p case is taken.
1142  */
1143 #define MCUX_CSSL_FP_SWITCH_TAKEN(...) \
1144   MCUX_CSSL_FP_SWITCH_TAKEN_IMPL(__VA_ARGS__)
1145 
1146 /**
1147  * @def MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT
1148  * @brief Expected that default case is handled from a switch.
1149  * @api
1150  * @ingroup csslFpSwitch
1151  *
1152  * This expectation macro indicates to the flow protection mechanism that the
1153  * switch declared by #MCUX_CSSL_FP_SWITCH_DECL with the given \p id has
1154  * executed the default case (under the given \p condition). For example:
1155  * @code
1156  * MCUX_CSSL_FP_SWITCH_DECL(someSwitchIdentifier);
1157  * switch (arg)
1158  * {
1159  *   case 0xC0DEu:
1160  *   {
1161  *     result = 0xC0DEu;
1162  *     MCUX_CSSL_FP_SWITCH_CASE(someSwitchIdentifier, 0xC0DEu);
1163  *     break;
1164  *   }
1165  *   default:
1166  *   {
1167  *     result = 0;
1168  *     MCUX_CSSL_FP_SWITCH_DEFAULT(someSwitchIdentifier);
1169  *     break;
1170  *   }
1171  * }
1172  *
1173  * MCUX_CSSL_FP_FUNCTION_EXIT(someFunction, result,
1174  *   // Option 1: provide the condition as part of the switch expectation.
1175  *   MCUX_CSSL_FP_SWITCH_TAKEN(argCheck, 0xC0DEu, 0xC0DEu == arg),
1176  *   // Option 2: place the switch expectation in a conditional block.
1177  *   MCUX_CSSL_FP_CONDITIONAL(0xC0DEu != arg),
1178  *     MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT(someSwitchIdentifier)
1179  *   )
1180  * );
1181  * @endcode
1182  *
1183  * @declaration{MCUX_CSSL_FP_SWITCH_DECL}
1184  * @event{MCUX_CSSL_FP_SWITCH_DEFAULT}
1185  *
1186  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
1187  * @see MCUX_CSSL_FP_FUNCTION_EXIT
1188  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
1189  * @see MCUX_CSSL_FP_EXPECT
1190  *
1191  * @param ...    The following parameters need to be passed (comma separated):
1192  *        - id:        Identifier of the flow protected switch.
1193  *        - condition: Optional, condition under which the default case is taken.
1194  */
1195 #define MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT(...) \
1196   MCUX_CSSL_FP_SWITCH_TAKEN_DEFAULT_IMPL(__VA_ARGS__)
1197 
1198 
1199 
1200 /**
1201  * @defgroup csslFpExpect Expectation handling
1202  * @brief Expectation handling support functionality.
1203  *
1204  * @ingroup mcuxCsslFlowProtection
1205  */
1206 
1207 /**
1208  * @def MCUX_CSSL_FP_EXPECT
1209  * @brief Declaration(s) of expected code flow behavior.
1210  * @api
1211  * @ingroup csslFpExpect
1212  *
1213  * This macro can be used to indicate expectations in the function body at
1214  * another location than the function entry or exit.
1215  *
1216  * @note In general the use of this macro is discouraged, to avoid a potential
1217  * security and/or code-size impact. However, it may be usefull for complex
1218  * code, where an intermediate update can actually save code, since conditions
1219  * for expectations can than be locallized.
1220  *
1221  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED,MCUX_CSSL_FP_LOOP_ITERATIONS,MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE,MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE,MCUX_CSSL_FP_SWITCH_TAKEN}
1222  *
1223  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
1224  * @see MCUX_CSSL_FP_FUNCTION_EXIT
1225  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
1226  * @see MCUX_CSSL_FP_CONDITIONAL
1227  *
1228  * @param ...    The following parameters need to be passed (comma separated):
1229  *        - expect: One or more (comma separated) declarations of expected code
1230  *                  flow behavior.
1231  */
1232 #define MCUX_CSSL_FP_EXPECT(...) \
1233   MCUX_CSSL_FP_EXPECT_IMPL(__VA_ARGS__)
1234 
1235 /**
1236  * @def MCUX_CSSL_FP_CONDITIONAL
1237  * @brief Handling of conditionally expected code flow behavior.
1238  * @api
1239  * @ingroup csslFpExpect
1240  *
1241  * This macro can be used to indicate expectations that are only true under a
1242  * given \p condition.
1243  *
1244  * @expectation{MCUX_CSSL_FP_FUNCTION_CALLED,MCUX_CSSL_FP_LOOP_ITERATIONS,MCUX_CSSL_FP_BRANCH_TAKEN_POSITIVE,MCUX_CSSL_FP_BRANCH_TAKEN_NEGATIVE,MCUX_CSSL_FP_SWITCH_TAKEN}
1245  *
1246  * @see MCUX_CSSL_FP_FUNCTION_ENTRY
1247  * @see MCUX_CSSL_FP_FUNCTION_EXIT
1248  * @see MCUX_CSSL_FP_FUNCTION_EXIT_WITH_CHECK
1249  * @see MCUX_CSSL_FP_EXPECT
1250  *
1251  * @param condition Condition under which the given expectations apply.
1252  * @param ...    One or more (comma separated) declarations of expected code
1253  *               flow behavior.
1254  */
1255 #define MCUX_CSSL_FP_CONDITIONAL(condition, ...) \
1256   MCUX_CSSL_FP_CONDITIONAL_IMPL(condition, __VA_ARGS__)
1257 
1258 #endif /* MCUX_CSSL_FLOW_PROTECTION_H_ */
1259