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